package com.zz.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zz.common.ZohoRecord;
import com.zz.service.ContractService;
import com.zz.utils.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ContractServiceImpl implements ContractService {

    @Autowired
    ZohoRecord zohoRecord;

    @Autowired
    BUtils bUtils;

    @Value("${zoho.zipFileDest}")
    private String zipFileDest;


    public static final String ip = "120.131.13.95";
    public static final String port = "7666";
    public static final String op = "1";
    public static final String aKey = "YP17K9Cu3J9OElMAYgye";
    public static final String mobile = "13438983210";
    public static final String psKey = "Asdqwe@123";

    @Async("asyncPoolTaskExecutor")
    @SneakyThrows
    @Override
    public ResultUtil<String> getDocTemplate(String contractId, String operationId) {

        log.info("contractId = {},operationId = {}", contractId, operationId);
        if (StringUtils.isBlank(contractId) || StringUtils.isBlank(operationId)) {
            return ResultUtil.error("入参为空");
        }
        ResultUtil<String> resultUtil;

        // 1 校验条件，当前操作人
        boolean isCheck = false;
        List<JSONObject> userData = CrmApiUtil.getUserDataById(zohoRecord.getAccessToken(), operationId);
        if (!CollectionUtils.isEmpty(userData)) {
            JSONObject user = userData.get(0);
            JSONObject profile = user.getJSONObject("profile");
            if (Objects.nonNull(profile)) {
                String roleName = profile.getString("name");
                log.info("当前用户角色名称：" + roleName);
                if (roleName.equalsIgnoreCase("客服助理") ||
                        roleName.equalsIgnoreCase("发货组客服组长") ||
                        roleName.equalsIgnoreCase("购销服务部经理") ||
                        roleName.equalsIgnoreCase("系统管理员") ||
                        roleName.equalsIgnoreCase("Administrator")) {
                    isCheck = true;
                }
            }
        }

        if (isCheck) {
            // 2 获取token
            Map<String, Object> tokenMap = getToken();
            if (tokenMap.containsKey("ERROR")) {
                return ResultUtil.error((String) tokenMap.get("ERROR"));
            }
            // 3 过滤合同数据，根据id循环调试，是否生成文件，获取文件流
            resultUtil = filterContractData(contractId, tokenMap, 1);
        } else {
            return ResultUtil.error("当前用户角色没有权限");
        }
        return resultUtil;
    }

    public Map<String, Object> getToken() {
        log.info("===== 第一步【获取token】 =====");
        String url = "http://" + ip + ":" + port + "/?OP=" + op + "&AKey=" + aKey + "&Mobile=" + mobile + "&PsKey=" + psKey;
        JSONObject data = HttpUtil.getData(url, new HashMap<>());
        Map<String, Object> map = new HashMap<>();
        String aReturn = data.getString("Return");
        if (!aReturn.equalsIgnoreCase("100:Success")) {
            map.put("ERROR", "获取合同文档token失败");
        } else {
            map.put("httpServerIP", data.getString("HttpServerIP"));
            map.put("httpPort", data.getString("HttpPort"));
            map.put("zTIdx", data.getString("ZTIdx"));
            map.put("token", data.getString("Token"));
        }
        return map;
    }

    /**
     * @param type type = 1 ,电子合同模板对接
     *             type = 2 ,生成2022市场营销服务协议模板
     */
    public ResultUtil<String> filterContractData(String contractId, Map<String, Object> tokenMap, int type) {
        log.info("===== 第二步【过滤合同数据，合同id = " + contractId + "】 =====");
        ResultUtil<String> resultUtil = ResultUtil.success();
        // crm数据
        JSONObject crmContractData = BiologicalApiUtil.getContractData(zohoRecord.getAccessToken(), contractId);
        if (Objects.isNull(crmContractData)) {
            return ResultUtil.error("合同数据为空");
        }
        if (type == 2) {
            resultUtil = provincialGeneration2022(contractId, crmContractData, tokenMap);
        }
        if (type == 1) {
            JSONObject layout = crmContractData.getJSONObject("Layout");
            if (Objects.nonNull(layout)) {
                String name = layout.getString("name");
                log.info("布局 = " + name);
                if ("商业经销协议".equalsIgnoreCase(name) || "经销推广协议".equals(name)) {
                    resultUtil = full(contractId, crmContractData, tokenMap);
                } else if ("市场推广服务协议".equalsIgnoreCase(name)) {
                    resultUtil = provincialGeneration(contractId, crmContractData, tokenMap);
                } else if ("终端协议".equalsIgnoreCase(name)) {
                    resultUtil = other(contractId, crmContractData, tokenMap);
                }
            }
        }
        return resultUtil;
    }

    // 市场推广服务协议
    public ResultUtil<String> provincialGeneration(String contractId, JSONObject crmContractData, Map<String, Object> tokenMap) {

        // 查询合同配送商业公司
        List<JSONObject> cdcList = BiologicalApiUtil.getBusinessCompany(zohoRecord.getAccessToken(), contractId);

        // 查询销售指标
        List<JSONObject> dpList = BiologicalApiUtil.getSaleTarget(zohoRecord.getAccessToken(), contractId);

        // 查询合同开发指标
        List<JSONObject> cdliList = BiologicalApiUtil.getDevelopTarget(zohoRecord.getAccessToken(), contractId);
        // 查询合同目标医院
//        List<JSONObject> cthList = bUtils.getContractTargetHospital(zohoRecord.getAccessToken(), contractId);
        List<JSONObject> cthList = BiologicalApiUtil.getContractTargetHospital(zohoRecord.getAccessToken(),contractId);

        // 协议收款人信息
        List<JSONObject> caList = BiologicalApiUtil.getPayerMessage(zohoRecord.getAccessToken(), contractId);

        // 查询合同目标医院开发计划
        List<JSONObject> hdList = BiologicalApiUtil.getHospitalDevelop(zohoRecord.getAccessToken(),contractId);
        Map<String,JSONObject> hdMap = new HashMap<>();
        for (JSONObject hd : hdList) {
            hdMap.put(hd.getJSONObject("Target_Hospital_c").getString("id"),hd);
        }
        Map<String,JSONObject> cthMap = new HashMap<>();
        for(JSONObject cth : cthList) {
            cthMap.put(cth.getString("Target_Hospital_c"),cth);
        }
        // 合同名称
        String contractName = crmContractData.getString("Name");
        // 公立三级医院开发家数
        String totalSum_c = crmContractData.getString("TotalSum_c");
        // 零售价
        String retailPrice_c = crmContractData.getString("RetailPrice_c");
        // 定稿版补充条款
        String supplementary_c = crmContractData.getString("Supplementary_c");
        // 乙方出货价
        String unitPrice_c = crmContractData.getString("UnitPrice_c");
        // 渠道
        String saleChannel_c = crmContractData.getString("SaleChannel_c");
        // 业务签约人联系电话
        String customer_phone_c = crmContractData.getString("Customer_Phone_c");
        // 业务签约人身份证号
        String businessContractorIdCard_c = crmContractData.getString("BusinessContractorIdCard_c");
        // 分销最高结算底价
        String maximumDistributionPrice_c = crmContractData.getString("MaximumDistributionPrice_c");
        // 结算低价
        String current_agent_price_c = crmContractData.getString("Current_Agent_Price_c");
        // 协议开始日期
        String start_date_c = crmContractData.getString("Start_Date_c");
        // 协议结束日期
        String end_date_c = crmContractData.getString("End_Date_c");
        // 省份
        String agent_province_c = crmContractData.getString("Agent_Province_c");
        // 合同编号
        String contractCode_c = crmContractData.getString("ContractCode_c");
        // 实际结算渠道
        String actualRefundPolicy_c = crmContractData.getString("ActualRefundPolicy_c");
        // 应缴市场保证金
        String market_margin_payable_c = crmContractData.getString("Market_margin_payable_c");
        //推广性质
        String agent_style_c = crmContractData.getString("Agent_Stlye_c");
        //填表人所属部门
        String department_c = crmContractData.getString("Department_c");
        // 合同所有者
        JSONObject owner = crmContractData.getJSONObject("shareuser");
        // 缴纳保证金公司名称
        String PayCompany = crmContractData.getString("PayCompany");

        String ownerName = "";
        if (Objects.nonNull(owner)) {
            ownerName = owner.getString("name");
        }
        // 省区经理
        JSONObject bizProvinceManager_c = crmContractData.getJSONObject("BizProvinceManager_c");
        String tempName = Objects.nonNull(bizProvinceManager_c) ? bizProvinceManager_c.getString("name") : "";
        // 甲方名称
        StringBuilder aName = new StringBuilder(StringUtils.isBlank(tempName) ? ownerName : tempName);
        // 销售总监
        String sales_director_c = crmContractData.getString("Sales_Director_c");
        // 商销业务分类
        String businessType_c = crmContractData.getString("BusineType_c");
        // 申请结算渠道
        String applicationRefundPolicy_c = crmContractData.getString("ApplicationRefundPolicy_c");
        String manufacturer_c = "";
        // 生产企业
        String manufacturer_c1 = "";
        // 客户/业务签约人
        String agentName = "";
        JSONObject agents_c = crmContractData.getJSONObject("Agents_c");
        if (Objects.nonNull(agents_c)) {
            agentName = agents_c.getString("name");
        }

        String op = "21";
        String aPIClass = "TGFWXY004";
        String models = "";
        String packageId = "";
        String unit_c = "";  // 件装规格
        String settlementUnit_c = ""; // 结算单位
        // 商品名/ 商标名
        String brand_c = "";
        // 产品名称
        String product_name = "";
        String kaifa = "（1）3个月内至少送货2次；\r\n（2）累计销售不低于100（支/袋/盒）。"; // 注射
        // 推广产品（包装包材）
        JSONObject agent_product_package_c = crmContractData.getJSONObject("Agent_Product_Package_c");
        if (Objects.nonNull(agent_product_package_c)) {
            packageId = agent_product_package_c.getString("id");

            List<JSONObject> packingMaterial = BiologicalApiUtil.getPackingMaterial(zohoRecord.getAccessToken(), packageId);
            if (!CollectionUtils.isEmpty(packingMaterial)) {
                JSONObject aPackage = packingMaterial.get(0);
                manufacturer_c = aPackage.getString("Supplier_c"); // 供货方
                unit_c = aPackage.getString("PackingUnit_c");
                settlementUnit_c = aPackage.getString("SettlementUnit_c");

                String attribute_c = aPackage.getString("Attribute_c");
                if ("口服药品".equals(attribute_c)) {
                    kaifa = "（1）3个月内至少送货2次；\r\n（2）累计销售不低于50（支/袋/盒）。";
                }
                JSONObject productCEdit = aPackage.getJSONObject("Product_c"); // 产品
                if (Objects.nonNull(productCEdit)) {
                    String productId = productCEdit.getString("id");
                    List<JSONObject> product = BiologicalApiUtil.getProduct(zohoRecord.getAccessToken(), productId);
                    if (!CollectionUtils.isEmpty(product)) {
                        JSONObject jsonObject = product.get(0);
                        brand_c = jsonObject.getString("Brand_c");
                        product_name = jsonObject.getString("Product_Name");
                        manufacturer_c1 = jsonObject.getString("Manufacturer_c"); // 生产企业
                    }
                }
            }
        }
        if (StringUtils.isNotBlank(agent_style_c) && StringUtils.isNotBlank(department_c)) {
            if (agent_style_c.equalsIgnoreCase("省级代理")) {
                if (department_c.contains("一部")) {
                    if (applicationRefundPolicy_c.equalsIgnoreCase("CSO")
                        || applicationRefundPolicy_c.equalsIgnoreCase("灵活用工")) {
                        models = "2025合作意向书D（省代）--模板--v1.0适用于（一部产品）CSO";
                    }
                    if (applicationRefundPolicy_c.equalsIgnoreCase("底价")) {
                        models = "2025合作意向书D（省代）--模板--v1.0适用于（一部产品）底价";
                    }
                }
                if (department_c.contains("二部")) {
                    if (applicationRefundPolicy_c.equalsIgnoreCase("CSO")
                            || applicationRefundPolicy_c.equalsIgnoreCase("灵活用工")) {
                        models = "2025合作意向书D（省代）--模板--v1.0--适用于（二部产品）CSO";
                    }
                    if (applicationRefundPolicy_c.equalsIgnoreCase("底价")) {
                        models = "2025合作意向书D（省代）--模板--v1.0--适用于（二部产品）底价";
                    }
                }
            }
            if (agent_style_c.equalsIgnoreCase("医院代理")) {
                if (department_c.contains("一部")) {
                    if (applicationRefundPolicy_c.equalsIgnoreCase("CSO")
                            || applicationRefundPolicy_c.equalsIgnoreCase("灵活用工")) {
                        models = "2025合作意向书D（医院代理）--模板--v1.0适用于（一部产品）CSO";
                    }
                    if (applicationRefundPolicy_c.equalsIgnoreCase("底价")) {
                        models = "2025合作意向书D（医院代理）--模板--v1.0适用于（一部产品）底价";
                    }
                }
                if (department_c.contains("二部")) {
                    if (applicationRefundPolicy_c.equalsIgnoreCase("CSO")
                            || applicationRefundPolicy_c.equalsIgnoreCase("灵活用工")) {
                        models = "2025合作意向书D（医院代理）--模板--v1.0适用于（二部产品）CSO";
                    }
                    if (applicationRefundPolicy_c.equalsIgnoreCase("底价")) {
                        models = "2025合作意向书D（医院代理）--模板--v1.0适用于（二部产品）底价";
                    }
                }
            }
        }

        if (StringUtils.isNotBlank(tempName) && tempName.contains("空-")) {
            aName = new StringBuilder(sales_director_c);
        }

        if (StringUtils.isNotBlank(department_c) && department_c.equalsIgnoreCase("商销部")) {
            if (businessType_c.equalsIgnoreCase("第一终端") && StringUtils.isNotBlank(applicationRefundPolicy_c)) {
                if (applicationRefundPolicy_c.equalsIgnoreCase("CSO")
                        || applicationRefundPolicy_c.equalsIgnoreCase("灵活用工")) {
                    models = "2025合作意向书D--v1.2适用于（商销部）CSO";
                }
                if (applicationRefundPolicy_c.equalsIgnoreCase("底价")) {
                    models = "2025合作意向书D--v1.2适用于（商销部）底价";
                }
            }
        }
        if (StringUtils.isNotBlank(department_c) && department_c.equalsIgnoreCase("保健品销售部")) {
            aName = new StringBuilder(manufacturer_c);// 供货方
            models = "2025代理商合作协议--适用于（欧淬恩）市场协议：保健品线下";
        }

        // 处罚金额
        String fine = brand_c.contains("甘同") ? "5000" : "2000";

        String fileRtn = "0";
        // 乙方名称
        StringBuilder bName = new StringBuilder(agentName);
        int aNameLength = aName.length();
        for (int i = 0; i < 6 - aNameLength; i++) {
            aName.append("  ");
        }
        int bNameLength = bName.length();
        for (int i = 0; i < 6 - bNameLength; i++) {
            bName.append("  ");
        }

        String thirdClassHospital = totalSum_c == null ? "0" : totalSum_c;
        String retailPrice = retailPrice_c == null ? "/" : retailPrice_c;
        String st = supplementary_c == null ? "/" : supplementary_c.replace("<br>", "\r\n");
        String ut = unitPrice_c == null ? "/" : unitPrice_c;
        String channel = saleChannel_c == null ? "/" : saleChannel_c;
        String msd = market_margin_payable_c == null ? "/" : market_margin_payable_c;
        String cp = customer_phone_c == null ? "/" : customer_phone_c;
        String busIdCard = businessContractorIdCard_c == null ? "/" : businessContractorIdCard_c;
        String su = settlementUnit_c == null ? "/" : settlementUnit_c;
        String mdp = maximumDistributionPrice_c == null ? "/" : maximumDistributionPrice_c;

        StringBuilder data = new StringBuilder("[<甲方名称>]=" + aName
                + "[<乙方名称>]=" + bName
                + "[<乙方电话>]=" + cp
                + "[<所有人名称>]=" + checkString(ownerName)
                + "[<业务签约人身份证号码>]=" + checkString(busIdCard)
                + "[<产品名称规格>]=" + checkString(product_name)
                + "[<产品的商品名>]=" + checkString(brand_c)
                + "[<产品单位>]=" + checkString(su)
                + "[<产品的件装量>]=" + checkString(unit_c)
                + "[<产品生产厂家>]=" + checkString(manufacturer_c1)
                + "[<产品推广结算底价>]=" + checkString(current_agent_price_c)
                + "[<产品约定零售价>]=" + checkString(retailPrice)
                + "[<渠道>]=" + checkString(channel)
                + "[<处罚金额>]=" + checkString(fine)
                + "[<公立三级医院>]=" + checkString(thirdClassHospital)
                + "[<乙方出货价>]=" + checkString(ut)
                + "[<市场保证金>]=" + checkString(msd)
                + "[<协议起始日期>]=" + checkString(DateUtil.parseDateWord(start_date_c))
                + "[<协议结束日期>]=" + checkString(DateUtil.parseDateWord(end_date_c))
                + "[<推广区域省份>]=" + checkString(agent_province_c)
                + "[<结算底价不高于>]=" + checkString(mdp)
                + "[<补充条款>]=" + checkString(st)
                + "[<甲方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                + "[<乙方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                + "[<缴纳保证金公司名称>]=" + checkString(PayCompany)
                + "[<开发认定标准>]=" + kaifa
                + "[<合同协议编号>]=" + checkString(contractCode_c));


        // 遍历 销售指标
        System.out.println("处理【销售指标】中...");
        if (dpList.size() > 0) {
            // 正序排序
            dpList.sort(Comparator.comparingInt(x -> Integer.parseInt(x.getString("Year_c")) + Integer.parseInt(x.getString("Month_c"))));

            BigDecimal ds = new BigDecimal(0);
            data.append("[<销售指标>]=");
            int time = 1;
            for (JSONObject dp : dpList) {
                //System.out.println("处理条数 = " + time++);
                // 指标
                String target_c = dp.getString("Target_c");
                // 年
                String year_c = dp.getString("Year_c");
                // 月
                String month_c = dp.getString("Month_c");
                String target = target_c == null ? "0" : target_c;
                data.append(checkString(year_c)).append("年")
                        .append(checkString(month_c)).append("月")
                        .append("\t\t\t\t\t\t\t").append(checkString(target)).append("\r\n");
                BigDecimal num = new BigDecimal(target);
                ds = ds.add(num);
            }
            data.append("[<销售指标合计>]=").append(ds);
        } else {
            data.append("[<销售指标>]=/");
            data.append("[<销售指标合计>]=/");
        }
        System.out.println("处理【销售指标】结束");


        // 遍历 开发指标
        System.out.println("处理【开发指标】中...");
        if (cdliList.size() > 0) {
            // 正序排序
            cdliList.sort(Comparator.comparingInt(x -> Integer.parseInt(x.getString("Year_c")) + Integer.parseInt(x.getString("Month_c"))));

            BigDecimal ds = new BigDecimal(0);
            data.append("[<开发指标>]=");
            int time = 1;
            for (JSONObject cdli : cdliList) {
                //System.out.println("处理条数 = " + time++);

                // 年
                String year_c = cdli.getString("Year_c");
                // 月
                String month_c = cdli.getString("Month_c");
                // 开发指标
                String developmentIndex_c = cdli.getString("DevelopmentIndex_c");

                data.append(checkString(year_c)).append("年")
                        .append(checkString(month_c)).append("月")
                        .append("\t\t\t\t\t\t\t").append(checkString(developmentIndex_c)).append("\r\n");
                BigDecimal num = new BigDecimal(developmentIndex_c);
                ds = ds.add(num);
            }
            data.append("[<开发指标合计>]=").append(ds);
        } else {
            data.append("[<开发指标>]=/");
            data.append("[<开发指标合计>]=/");
        }
        System.out.println("处理【开发指标】结束");

        // 遍历 商业公司
        System.out.println("处理【商业公司】中...");
        if (cdcList.size() > 0) {
            data.append("[<配送商业公司名单>]=");

            for (int i = 0; i < cdcList.size(); i++) {
                //System.out.println("处理条数 = " + (i + 1));
                // 商业公司
                JSONObject businessCompany_c1 = cdcList.get(i).getJSONObject("BusinessCompany_c");
                if (Objects.nonNull(businessCompany_c1)) {
                    String businessCompany_c = businessCompany_c1.getString("name");
                    data.append(i + 1).append("\t").append(checkString(businessCompany_c)).append("\r\n");
                }
            }
        } else {
            data.append("[<配送商业公司名单>]=/");
        }
        System.out.println("处理【商业公司】结束");

        int limit = 50;
        // 合同目标医院id 查询 目标医院id
        Set<String> thIdList = cthList.stream().map(json -> json.getJSONObject("Target_Hospital_c").getString("id")).collect(Collectors.toSet());
        List<String> thIdListData = new ArrayList<>(thIdList);


        // 遍历 合同目标医院
        System.out.println("处理【合同目标医院】中...");
        if (cthList.size() > 0) {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < cthList.size(); i++) {
                //System.out.println("处理条数 = " + (i + 1));
                String hName = "";
                String nameTemp = "";
                // 目标医院

                String target_hospital_c = cthList.get(i).getJSONObject("Target_Hospital_c").getString("name").split("-")[0];

                if (StringUtils.isNotBlank(target_hospital_c)) {
                    hName = target_hospital_c.replace("（", "(").replace("）", ")");
                    nameTemp = getTemp(hName, 52);

                    // 机构性质
                    String institutional_c = cthList.get(i).getString("Institutional_c");
                    String institutional = institutional_c == null ? "/\t\t" : institutional_c + "\t";


                    // 合同目标医院 -> 目标医院 -> 合同目标医院开发计划
                    boolean isKFJH = false; // 是否有开发计划
                    JSONObject jsonObject = cthList.get(i);
                    String targetHospitalId = jsonObject.getJSONObject("Target_Hospital_c").getString("id");// 目标医院
                    // 目标销量
                    String target_quantity_c = hdMap.containsKey(targetHospitalId)?hdMap.get(targetHospitalId).getString("TargetQuantity_c"):"";
                    // 开发时限
                    String devDeadline_c = hdMap.containsKey(targetHospitalId)?hdMap.get(targetHospitalId).getString("DevelopmentTime_c"):"";

                    String targetQuantity = target_quantity_c == null ? "/" : target_quantity_c;

                    // 开发时间
                    //String dd = devDeadline_c == null ? "\t/\t" : devDeadline_c;
                    String dev = devDeadline_c == null ? "\t/\t" : devDeadline_c;
                    // 分值
                    String hospital_integral_c = checkString(cthList.get(i).getString("Hospital_Integral_c"));
                    // 开发状态
                    String hospital_status_c = checkString(cthList.get(i).getString("Hospital_Status_c"));

                    String dev2 = hospital_status_c.contains("已开发") ? hospital_status_c : dev;
                    if (!isKFJH) {
                        dev2 = hospital_status_c;
                    }

                    builder.append(i + 1).append("\t")
                            .append(hName).append(nameTemp)
                            .append(institutional).append("\t");//机构性质

                    // 目标医院 id
                    thIdList.add(cthList.get(i).getString("id"));
                }


            }
            data.append("[<目标医院名单>]=").append(builder);
        } else {
            data.append("[<目标医院名单>]=/");
        }
        System.out.println("处理【合同目标医院】结束");

        if (StringUtils.isBlank(models)) {
            return ResultUtil.error("models为空");
        } else {
            log.info("models=" + models);
        }

        Map<String, String> startAndEndTime = getStartAndEndTime(start_date_c, end_date_c);
        String startDate = startAndEndTime.get("startDate");
        String endDate = startAndEndTime.get("endDate");

        // 查询目标医院销售指标（就是产品流向每月汇总）
        List<JSONObject> tempList = new ArrayList<>();


        // 根据时间过滤
        List<JSONObject> thisList = new ArrayList<>();
        for (JSONObject jsonObject : tempList) {
            String year = jsonObject.getString("Year_c");
            String month = jsonObject.getString("Month_c");
            if (DateUtil.appendYearMonth(year, month, startDate, endDate)) {
                thisList.add(jsonObject);
            }
        }

        // 遍历 目标医院销售指标
        System.out.println("处理【目标医院销售指标】中");

        System.out.println("处理【目标医院销售指标】结束");

        String jsonStu = getJsonStu(models, data);
        String url = "";
        try {
            url = "http://" + tokenMap.get("httpServerIP") + ":" +
                    tokenMap.get("httpPort") + "/?Op=" + op +
                    "&ZTIdx=" + tokenMap.get("zTIdx") +
                    "&Token=" + tokenMap.get("token")
                    + "&APIClass=" + aPIClass + "&FileRtn=" + fileRtn;
        } catch (Exception e) {
            log.error("error:" + e);
        }
        log.info("jsonStu=" + jsonStu);
        Map<String, Object> resMap = HttpUtil.postJsonData(url, jsonStu.replaceAll("\\\\", "/"));

        if (checkResponseMap(resMap)) return ResultUtil.error("请求接口不通！");
        String workIDs = resMap.get("WorkIDs").toString();
        log.info("workIDs=" + workIDs);

        // 第三步 获取downFiles
        List<String> downFiles = getDownFiles(workIDs, tokenMap);

        // 第四步 生成文件
        // 模板增加乙方名称
        contractName = bName + "_" + contractName;
        generatorFile(downFiles, tokenMap, contractId, contractName);

        // 删除之前缓存的文件
        deleteFile();

        //删除临时文件
        bUtils.deleteContents(new File(zipFileDest));

        return ResultUtil.success();
    }

    /**
     * 第四步 生成文件
     *
     * @param downFiles    下载的文件
     * @param tokenMap     token
     * @param contractId   合同id
     * @param contractName 合同名称
     */
    public void generatorFile(List<String> downFiles, Map<String, Object> tokenMap, String contractId, String contractName) {
        if (!CollectionUtils.isEmpty(downFiles)) {
            log.info("===== 第四步【生成文件】 =====");
            log.info(" 文件名称：" + downFiles);
            for (String downFile2 : downFiles) {
                String[] downFile = downFile2.split(",");
                String downFileName = "";
                for (String s : downFile) {
                    if (s.contains("Doc")) {
                        downFileName = s;
                        break;
                    }
                }
                if (StringUtils.isBlank(downFileName)) continue;
                String opTemp = "4";
                String urlTemp = "http://" + tokenMap.get("httpServerIP") + ":" + tokenMap.get("httpPort") + "/?OP=" + opTemp
                        + "&ZTIdx=" + tokenMap.get("zTIdx") + "&Token=" + tokenMap.get("token")
                        + "&DownFile=" + downFileName;

                InputStream input = HttpUtil.getFileData(urlTemp, new HashMap<>());
                if (Objects.isNull(input)) {
                    log.info("文件流为空");
                } else {
                    log.info("准备将文件传送至CRM");
                    contractName = ContractUtil.getContractName(contractName);
                    String filePath = FileUtil.getRelativeResourceFilePath();
                    String fileName = contractName + ".doc";
                    String fileFullPath = filePath + File.separator + fileName;

                    File file = new File(filePath);
                    //判断文件路径是否存在
                    if (!file.exists()) {
                        boolean mkdirs = file.mkdirs();
                        if (mkdirs) {
                            log.info("已自动创建文件路径");
                        }
                    }
                    //生成文件
                    FileUtil.generatorFile(input, fileFullPath);

                    log.info("导入的文件 = " + fileName);

                    // 文件流方式
                    String url = "https://www.zohoapis.com.cn/crm/v3/Contract/" + contractId + "/Attachments";

                    JSONObject jsonObject = HttpUtil.postFileByFileStream(zohoRecord.getAccessToken(), fileFullPath, url);
                    if (jsonObject.toJSONString().contains("SUCCESS")) {
                        JSONArray data = jsonObject.getJSONArray("data");
                        List<JSONObject> list = data.toJavaList(JSONObject.class);
                        String attachmentId = list.get(0).getJSONObject("details").getString("id");

                        // 更新合同模板下的 签署协议模板ID 字段
                        JSONObject updateData = new JSONObject();
                        updateData.put("attachmentId_c", attachmentId);
                        updateData.put("EsignStatus_c", "未发送"); // 签署状态
                        CrmApiUtil.updateContractData(contractId, updateData);

                        log.info("传送成功，附件id = " + attachmentId);
                    } else {
                        log.info("传送失败" + jsonObject.toJSONString());
                    }
                }
            }
        }
    }

    /**
     * 第四步 生成文件
     *
     * @param downFiles    下载的文件
     * @param tokenMap     token
     * @param incentiveId  开发上量奖励id
     * @param contractName 合同名称
     */
    public void generatorIncentiveFile(List<String> downFiles, Map<String, Object> tokenMap, String incentiveId, String contractName) {
        if (!CollectionUtils.isEmpty(downFiles)) {
            log.info("===== 第四步【生成文件】 =====");
            log.info(" 文件名称：" + downFiles);
            for (String downFile2 : downFiles) {
                String[] downFile = downFile2.split(",");
                String downFileName = "";
                for (String s : downFile) {
                    if (s.contains("Doc")) {
                        downFileName = s;
                        break;
                    }
                }
                if (StringUtils.isBlank(downFileName)) continue;
                String opTemp = "4";
                String urlTemp = "http://" + tokenMap.get("httpServerIP") + ":" + tokenMap.get("httpPort") + "/?OP=" + opTemp
                        + "&ZTIdx=" + tokenMap.get("zTIdx") + "&Token=" + tokenMap.get("token")
                        + "&DownFile=" + downFileName;

                InputStream input = HttpUtil.getFileData(urlTemp, new HashMap<>());
                if (Objects.isNull(input)) {
                    log.info("文件流为空");
                } else {
                    log.info("准备将文件传送至CRM");
                    contractName = ContractUtil.getContractName(contractName);
                    String filePath = FileUtil.getRelativeResourceFilePath();
                    String fileName = contractName + ".doc";
                    String fileFullPath = filePath + File.separator + fileName;


                    File file = new File(filePath);
                    //判断文件路径是否存在
                    if (!file.exists()) {
                        boolean mkdirs = file.mkdirs();
                        if (mkdirs) {
                            log.info("已自动创建文件路径");
                        }
                    }
                    //生成文件
                    FileUtil.generatorFile(input, fileFullPath);

                    log.info("导入的文件 = " + fileName);

                    // 文件流方式
                    String url = "https://www.zohoapis.com.cn/crm/v3/Incentive_Agreement/" + incentiveId + "/Attachments";

                    JSONObject jsonObject = HttpUtil.postFileByFileStream(zohoRecord.getAccessToken(), fileFullPath, url);
                    if (jsonObject.toJSONString().contains("SUCCESS")) {

                        JSONArray data = jsonObject.getJSONArray("data");
                        List<JSONObject> list = data.toJavaList(JSONObject.class);
                        String attachmentId = list.get(0).getJSONObject("details").getString("id");

                        // 更新上量奖励模板下的 签署协议模板ID 字段
                        JSONObject updateData = new JSONObject();
                        updateData.put("attachmentId_c", attachmentId);
                        updateData.put("EsignStatus_c", "未发送"); // 签署状态
                        CrmApiUtil.updateIncentiveData(incentiveId, updateData);
                        log.info("传送成功");
                    } else {
                        log.info("传送失败" + jsonObject.toJSONString());
                    }
                }
            }
        }
    }

    //第三步 获取downFiles
    public List<String> getDownFiles(String workIDs, Map<String, Object> tokenMap) {
        log.info("===== 第三步【获取downFiles】 =====");
        List<String> downFiles = new ArrayList<>();
        boolean isContinue = true; // 是否继续查询文件
        int time = 0;
        do {
            if (StringUtils.isNotBlank(workIDs)) {
                String productStu;
                Map<String, Object> map = thirdStepOwn(tokenMap, workIDs);
                if ("100:Success".equalsIgnoreCase(map.get("Return").toString()) && "2".equalsIgnoreCase(map.get("ProductStu").toString())) {
                    downFiles.add(map.get("DownFiles").toString());
                    productStu = map.get("ProductStu").toString();
                    log.info(" 文件生成状态:" + productStu + ";请求次数：" + time++);
                    isContinue = false;
                } else {
                    log.info("文件生成中");
                    try {
                        TimeUnit.SECONDS.sleep(60);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                isContinue = false;
            }

        } while (isContinue);
        log.info("文件已生成");
        return downFiles;
    }

    // 第三步 根据workIDs获取downFiles
    public static Map<String, Object> thirdStepOwn(Map<String, Object> tokenMap, String workIDs) {

        String op = "3";
        String url = "http://" + tokenMap.get("httpServerIP") + ":" + tokenMap.get("httpPort") + "/?OP=" + op + "&ZTIdx=" + tokenMap.get("zTIdx") + "&Token=" + tokenMap.get("token")
                + "&WorkID=" + workIDs;
        return HttpUtil.getData(url, new HashMap<>());
    }

    public BigDecimal getBigDecimal(BigDecimal bigDecimal, Object obj) {
        int addNum = Integer.parseInt(obj.toString());
        return bigDecimal.add(new BigDecimal(addNum));

    }

    // 商业经销协议
    public ResultUtil<String> full(String contractId, JSONObject crmContractData, Map<String, Object> tokenMap) {

        // 查询配送产品
        List<JSONObject> ccList = BiologicalApiUtil.getDistributionProduct(zohoRecord.getAccessToken(), contractId);

        // 合同名称
        String contractName = crmContractData.getString("Name");
        // 佣金方式
        String commissionWay_c = crmContractData.getString("CommissionWay_c");
        // 定稿版补充条款
        String supplementary_c = crmContractData.getString("Supplementary_c");
        // 应缴市场保证金
        String market_margin_payable_c = crmContractData.getString("Market_margin_payable_c");
        // 商业奖励政策点位（%）
        String bizRewardPolicyPoint_c = crmContractData.getString("BizRewardPolicyPoint_c");
        // 省份
        String agent_province_c = crmContractData.getString("Agent_Province_c");
        // 商业扣率（%）
        String bizCutRate_c = crmContractData.getString("BizCutRate_c");
        // 商业经销协议计划签订账期天数
        String moneyBackDays_c = crmContractData.getString("MoneyBackDays_c");
        // 协议开始日期
        String start_date_c = crmContractData.getString("Start_Date_c");
        // 协议结束日期
        String end_date_c = crmContractData.getString("End_Date_c");
        // 合同编号
        String contractCode_c = crmContractData.getString("ContractCode_c");
        // 配送区域
        String agent_Region_c = crmContractData.getString("Agent_Region_c");
        // 客户/业务签约人
        String agentName = "";
        JSONObject agents_c = crmContractData.getJSONObject("Agents_c");
        if (Objects.nonNull(agents_c)) {
            agentName = agents_c.getString("name");
        }
        // 合同所有者
        JSONObject owner = crmContractData.getJSONObject("shareuser");
        String ownerName = "";
        if (Objects.nonNull(owner)) {
            ownerName = owner.getString("name");
        }
        // C端建议零售价
        String c_End_Retail_Price_c = crmContractData.getString("C_End_Retail_Price_c");
        c_End_Retail_Price_c = c_End_Retail_Price_c == null ? "/" : c_End_Retail_Price_c + "元";
        // 根据产品性质判断药瓶 非药品
        String bankNumber = "";
        String op = "21";
        String aPIClass = "TGFWXY004";
        String models = "";
        String fileRtn = "0";
        if ("赊销".equals(commissionWay_c)) {
            models = "2025年商业配送协议V1.1-赊销模板--适用于赊销模式";
        }
        if ("预付款".equals(commissionWay_c)) {
            models = "2025年商业配送协议V1.1-全款模板--适用于全款模式";
        }
        if (agent_Region_c != null && agent_Region_c.contains("电商")) {
            models = "2025年商业配送协议V1.1-全款模板--适用于电商平台";
        }
        JSONObject shareuser = crmContractData.getJSONObject("shareuser");
        String shareuserName = "";
        if (Objects.nonNull(shareuser)) {
            shareuserName = shareuser.getString("name");
        }
        //填表人所属部门
        String department_c = crmContractData.getString("Department_c");
        if (StringUtils.isNotBlank(department_c) && department_c.equalsIgnoreCase("保健品销售部")) {
            models = "2025代理商合作协议--适用于（欧淬恩）市场协议：保健品线下";
        }


        Set<String> compNames = new HashSet<>();
        for (JSONObject jsonObject : ccList) {
            JSONObject product_delivery_c = jsonObject.getJSONObject("Product_Delivery_c");
            String id = product_delivery_c.getString("id"); // 包装包材id
            List<JSONObject> packingMaterialByProduct = BiologicalApiUtil.getPackingMaterialByProduct(zohoRecord.getAccessToken(), id);
            if (packingMaterialByProduct.size() > 0) {
                String supplier_c = packingMaterialByProduct.get(0).getString("Supplier_c");
                compNames.add(supplier_c);
            }
        }

        String st = supplementary_c == null ? "/" : supplementary_c.replace("<br>", "\r\n");
        String brp = bizRewardPolicyPoint_c == null ? "/" : bizRewardPolicyPoint_c + "%";
        String msd = market_margin_payable_c == null ? "/" : market_margin_payable_c;
        if (compNames.size() > 0) {
            for (String compName : compNames) {
                String compName2 = compName;
                // 判断供货方
                ArrayList<JSONObject> cList = new ArrayList<>();
                HashMap<String, Object> tempMap = new HashMap<>();
                String shippingPrice_c = "";
                String unit_c = "";
                String ppname = "";
                for (JSONObject jsonObject : ccList) {
                    JSONObject product_delivery_c = jsonObject.getJSONObject("Product_Delivery_c");
                    // 结算底价
                    shippingPrice_c = jsonObject.getString("AppliedTicketPrice_c");
                    shippingPrice_c = shippingPrice_c == null ? "/" : shippingPrice_c + "元";
                    String id = product_delivery_c.getString("id"); // 包装包材id
                    List<JSONObject> packingMaterialByProduct = BiologicalApiUtil.getPackingMaterialByProduct(zohoRecord.getAccessToken(), id);
                    JSONObject packingMaterial = packingMaterialByProduct.get(0);
                    ppname = packingMaterial.getString("Name");
                    String supplier_c = packingMaterial.getString("Supplier_c");
                    unit_c = packingMaterial.getString("Unit_c");

                    if (supplier_c.equalsIgnoreCase(compName)) {
                        // 去重
                        String name = packingMaterial.getString("Name");
                        // 包装/包材
                        String wrapper_c = packingMaterial.getString("Wrapper_c");
                        // 制剂规格
                        String standard_c = packingMaterial.getString("Standard_c");

                        // 产品性质
                        String ProductType_c = packingMaterial.getString("ProductType_c");
                        jsonObject.put("ProductType_c", ProductType_c);

                        if (tempMap.get(name + standard_c + wrapper_c) == null) {
                            tempMap.put(name + standard_c + wrapper_c, jsonObject);
                            cList.add(packingMaterial);
                        }
                    }
                }

                if ("西藏润禾药业有限公司".equals(compName)) {
                    compName2 = "成都苑东生物制药股份有限公司";
                } else if ("西藏海金药业有限公司".equals(compName) || "成都国为生物医药有限公司".equals(compName)) {
                    compName2 = "成都天台山制药股份有限公司";
                }
                String data = "[<甲方名称>]=" + compName
                        + "[<公司名称>]=" + compName2
                        + "[<乙方名称>]=" + agentName
                        + "[<合作区域省份>]=" + checkString(agent_province_c)
                        + "[<结束价格的商业扣率>]=" + checkString(bizCutRate_c) + "%"
                        + "[<合作奖励的商业奖励政策>]=" + checkString(brp)
                        + "[<商业经销协议计划签订账期天数>]=" + checkString(moneyBackDays_c)
                        + "[<市场保证金>]=" + checkString(msd)
                        + "[<协议起始日期>]=" + checkString(DateUtil.parseDateWord(start_date_c))
                        + "[<协议结束日期>]=" + checkString(DateUtil.parseDateWord(end_date_c))
                        + "[<补充条款>]=" + checkString(st)
                        + "[<甲方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                        + "[<乙方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                        + "[<产品名称规格>]=" + checkString(ppname)
                        + "[<产品单位>]=" + checkString(unit_c)
                        + "[<产品约定零售价>]=" + c_End_Retail_Price_c
                        + "[<产品推广结算底价>]=" + shippingPrice_c
                        + "[<推广区域省份>]=" + checkString(agent_province_c)
                        + "[<渠道>]=" + checkString(agent_Region_c)
                        + "[<市场保证金>]=" + checkString(market_margin_payable_c)
                        + "[<所有人名称>]=" + checkString(ownerName)
                        + "[<合同协议编号>]=" + checkString(contractCode_c);

                StringBuilder JSONStu = new StringBuilder("{");
                JSONStu.append("\"Models\":\"").append(models).append("\",");

                if ("赊销".equals(commissionWay_c) || "预付款".equals(commissionWay_c) && !department_c.equalsIgnoreCase("保健品销售部")) {
                    JSONStu.append("\"DetailData1\":[");
                    for (int i = 0; i < cList.size(); i++) {
                        JSONObject jsonObject = cList.get(i);
                        // 名称
                        String name = jsonObject.getString("Name");
                        // 包装/包材
                        String wrapper_c = jsonObject.getString("Wrapper_c");
                        // 制剂规格
                        String standard_c = jsonObject.getString("Standard_c");
                        // 批准文号
                        String approvalNumber_c = jsonObject.getString("ApprovalNumber_c");

                        JSONStu.append("{\"RowData\":\"" + "[<T2>]=").append(name).append("[<T3>]=").append(standard_c)
                                .append("[<T4>]=").append(wrapper_c).append("[<T5>]=").append(approvalNumber_c).append("\"}");

                        if (i < cList.size() - 1) {
                            JSONStu.append(",");
                        } else {
                            JSONStu.append(",{\"RowData\":\"[<T2>]=以下空白\"}");
                        }
                    }
                    JSONStu.append("],");
                }
                if (department_c.equalsIgnoreCase("保健品销售部")) {
                    JSONStu.append("\"DetailData1\":[");
                    int i = 0;
                    for (JSONObject jsonObject : ccList) {
                        JSONObject product_delivery_c = jsonObject.getJSONObject("Product_Delivery_c");
                        // 结算底价

                        shippingPrice_c = jsonObject.getString("AppliedTicketPrice_c");
                        shippingPrice_c = shippingPrice_c == null ? "/" : shippingPrice_c + "元";
                        String id = product_delivery_c.getString("id"); // 包装包材id
                        List<JSONObject> packingMaterialByProduct = BiologicalApiUtil.getPackingMaterialByProduct(zohoRecord.getAccessToken(), id);
                        JSONObject packingMaterial = packingMaterialByProduct.get(0);
                        ppname = packingMaterial.getString("Name");
                        String supplier_c = packingMaterial.getString("Supplier_c");
                        String SettlementUnit_c = packingMaterial.getString("SettlementUnit_c");

                        JSONStu.append("{\"RowData\":\"" + "[<T2>]=").append(ppname).append("[<T3>]=").append(SettlementUnit_c)
                                .append("[<T4>]=").append(supplier_c).append("[<T5>]=").append(shippingPrice_c).append("\"}");
                        if (i < ccList.size() - 1) {
                            JSONStu.append(",");
                        } else {
                            JSONStu.append(",{\"RowData\":\"[<T2>]=以下空白\"}");
                        }
                        i++;
                    }
                    JSONStu.append("],");
                }


                JSONStu.append("\"Data\":\"").append(data).append("\"}");
                log.info("JSONStu = " + JSONStu);

                String url = "";
                try {
                    url = "http://" + tokenMap.get("httpServerIP") + ":" +
                            tokenMap.get("httpPort") + "/?Op=" + op +
                            "&ZTIdx=" + tokenMap.get("zTIdx") +
                            "&Token=" + tokenMap.get("token")
                            + "&APIClass=" + aPIClass + "&FileRtn=" + fileRtn;
                } catch (Exception e) {
                    log.error(" e:" + e);
                }

                Map<String, Object> resMap = HttpUtil.postJsonData(url, JSONStu.toString());

                if (checkResponseMap(resMap)) return ResultUtil.error("请求接口不通！");
                String workIDs = resMap.get("WorkIDs").toString();
                log.info(" workIDs:" + workIDs);

                // 第三步 获取downFiles
                List<String> downFiles = getDownFiles(workIDs, tokenMap);

                // 第四步 生成文件
                // 模板增加公司名称
                contractName = compName + "_" + contractName;
                generatorFile(downFiles, tokenMap, contractId, contractName);

                // 删除之前缓存的文件
                deleteFile();
            }

        } else {
            log.info("推广产品（包装包材）为空");
        }
        return ResultUtil.success();
    }

    public boolean checkResponseMap(Map<String, Object> resMap) {
        return resMap == null || !"100:Success".equals(resMap.get("Return").toString());
    }

    // 终端协议
    public ResultUtil<String> other(String contractId, JSONObject crmContractData, Map<String, Object> tokenMap) {
        String op = "21";
        String aPIClass = "TGFWXY004";
        String models = "";
        // 商销业务分类
        String businessType_c = crmContractData.getString("BusineType_c");
        // 合同所有者
        JSONObject owner = crmContractData.getJSONObject("shareuser");
        String ownerName = "";
        if (Objects.nonNull(owner)) {
            ownerName = owner.getString("name");
        }
        // 省区经理
        JSONObject bizProvinceManager_c = crmContractData.getJSONObject("BizProvinceManager_c");
        // 销售总监
        String sales_director_c = crmContractData.getString("Sales_Director_c");
        String department_c = crmContractData.getString("Department_c");
        // 协议开始日期
        String start_date_c = crmContractData.getString("Start_Date_c");
        // 协议结束日期
        String end_date_c = crmContractData.getString("End_Date_c");
        String agentName = "";
        JSONObject agents_c = crmContractData.getJSONObject("Agents_c");
        if (Objects.nonNull(agents_c)) {
            agentName = agents_c.getString("name");
        }
        String manufacturer_c = "";
        // 推广产品
        JSONObject agent_product_package_c1 = crmContractData.getJSONObject("Agent_Product_Package_c1");
        if (Objects.nonNull(agent_product_package_c1)) {
            String id = agent_product_package_c1.getString("id");
            List<JSONObject> productList = BiologicalApiUtil.getProduct(zohoRecord.getAccessToken(), id);
            if (!CollectionUtils.isEmpty(productList)) {
                JSONObject product = productList.get(0);
                manufacturer_c = product.getString("Supplier_c");
            }
        }
        //产品生产厂家
        String manufacturer_c1 = "";
        // 推广产品（包装包材）
        JSONObject agent_product_package_c = crmContractData.getJSONObject("Agent_Product_Package_c");
        if (Objects.nonNull(agent_product_package_c)) {
            String id = agent_product_package_c.getString("id");
            List<JSONObject> productList = BiologicalApiUtil.getPackingMaterial(zohoRecord.getAccessToken(), id);
            if (!CollectionUtils.isEmpty(productList)) {
                JSONObject product = productList.get(0);
                manufacturer_c1 = product.getString("Manufacturer_c");
                manufacturer_c = product.getString("Supplier_c");
            }
        }

        // 乙方性质
        String correspondingPolicy_c = crmContractData.getString("CorrespondingPolicy_c");
        // 申请结算渠道
        String applicationRefundPolicy_c = crmContractData.getString("ApplicationRefundPolicy_c");

        StringBuilder aName = new StringBuilder(bizProvinceManager_c == null ? ownerName : bizProvinceManager_c.getString("name"));// 甲方名称
        if (correspondingPolicy_c.contains("公对公签")) {
            aName = new StringBuilder(manufacturer_c);// 供货方
        }
        StringBuilder bName = new StringBuilder(agentName);// 乙方名称
        String name = "";
        if (Objects.nonNull(crmContractData.getJSONObject("NewCommercialCompany_c"))) {
            name = crmContractData.getJSONObject("NewCommercialCompany_c").getString("name");
        }
        String cName = name == null ? "/" : name;// 丙方名称
        // 推广产品（包装包材）
        String packageId = "";
        String unit_c = "";  // 件装规格
        String settlementUnit_c = ""; // 结算单位
        if (Objects.nonNull(agent_product_package_c)) {
            packageId = agent_product_package_c.getString("id");
            unit_c = agent_product_package_c.getString("PackingUnit_c");
            settlementUnit_c = agent_product_package_c.getString("SettlementUnit_c");
        }
        // 商品名/ 商标名
        String brand_c = "";
        // 产品名称
        String product_name = "";
        List<JSONObject> packingMaterial = BiologicalApiUtil.getPackingMaterial(zohoRecord.getAccessToken(), packageId);
        String kaifa = "（1）3个月内至少送货2次；\r\n（2）累计销售不低于100（支/袋/盒）。"; // 注射
        if (!CollectionUtils.isEmpty(packingMaterial)) {
            JSONObject aPackage = packingMaterial.get(0);
            JSONObject productCEdit = aPackage.getJSONObject("Product_c");
            String productId = productCEdit.getString("id");
            List<JSONObject> product = BiologicalApiUtil.getProduct(zohoRecord.getAccessToken(), productId);
            JSONObject jsonObject = product.get(0);
            brand_c = jsonObject.getString("Brand_c");
            product_name = jsonObject.getString("Product_Name");
            String attribute_c = aPackage.getString("Attribute_c");
            if ("口服药品".equals(attribute_c)) {
                kaifa = "（1）3个月内至少送货2次；\r\n（2）累计销售不低于50（支/袋/盒）。";
            }
        }

        String agent_style_c = crmContractData.getString("Agent_Stlye_c");

        if ("省级代理".equals(agent_style_c)) {
            if (department_c.contains("一部")) {
                models = "2025合作意向书Y（省代）--模板--v1.0适用于（一部产品）";
            }
            if (department_c.contains("二部")) {
                models = "2025合作意向书Y（省代）--模板--v1.0适用于（二部产品）";
            }
        }
        if ("医院代理".equals(agent_style_c)) {
            if (department_c.contains("一部")) {
                models = "2025合作意向书Y（医院代理）--模板--v1.0适用于（一部产品）";
            }
            if (department_c.contains("二部")) {
                models = "2025合作意向书Y（医院代理）--模板--v1.0适用于（二部产品）";
            }
        }
        if ("商销部".equals(department_c)) {
            if (StringUtils.isNotBlank(businessType_c) && businessType_c.equals("第一终端")) {
                models = "2025合作意向书Y--v1.2适用于（商销部）";
            }
        }

        // 查询合同目标医院
        List<JSONObject> cthList = bUtils.getContractTargetHospital(zohoRecord.getAccessToken(), contractId);
        Map<String,JSONObject> cthMap = new HashMap<>();
        for (JSONObject cth : cthList) {
            cthMap.put(cth.getString("Target_Hospital_c"),cth);
        }

        //log.info("cthList:" + cthList.size());

        // 合同目标医院id 查询 目标医院id
        Set<String> thIdList = cthList.stream().map(json -> json.getJSONObject("Target_Hospital_c").getString("id")).collect(Collectors.toSet());
        List<String> thIdListData = new ArrayList<>(thIdList);

        Map<String, String> startAndEndTime = getStartAndEndTime(start_date_c, end_date_c);
        String startDate = startAndEndTime.get("startDate");
        String endDate = startAndEndTime.get("endDate");

        // 查询目标医院销售指标
        List<JSONObject> tempList = new ArrayList<>();
        int limit = 50; // 批量查询50条数据
        Set<String> jsonData = new HashSet<>();

        // 根据时间过滤
        List<JSONObject> thisList = new ArrayList<>();
        for (JSONObject jsonObject : tempList) {
            String year = jsonObject.getString("Year_c");
            String month = jsonObject.getString("Month_c");
            if (DateUtil.appendYearMonth(year, month, startDate, endDate)) {
                thisList.add(jsonObject);
            }
        }
        log.info("目标医院销售指标 = " + thisList.size());

        // 合同目标医院id
        List<String> idListData = cthList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());

        List<JSONObject> targetHospitalBusiness = new ArrayList<>();
        Set<String> jsonTargetData = new HashSet<>();
        for (int i = 1; i <= idListData.size(); i++) {
            jsonTargetData.add(idListData.get(i - 1));
            if (i % limit == 0 || ((idListData.size() - i) < limit && (i == idListData.size()))) {
                List<JSONObject> hospitalBusinessBatch = BiologicalApiUtil.getTargetHospitalBusinessBatch(zohoRecord.getAccessToken(), jsonTargetData);
                targetHospitalBusiness.addAll(hospitalBusinessBatch);
                jsonTargetData = new HashSet<>();
            }
        }

        // 查询合同目标医院配送商业
        List<JSONObject> chpdList = new ArrayList<>(targetHospitalBusiness);


        // 协议收款人信息
        List<JSONObject> caList = BiologicalApiUtil.getPayerMessage(zohoRecord.getAccessToken(), contractId);

        String dbcName = "/";
        if (chpdList.size() > 0) {
            // 配送商业
            dbcName = chpdList.get(0).getJSONObject("DeliveryBuCompany_c").getString("name");
        }
        String bidding_price_c = crmContractData.getString("Bidding_Price_c");

        BigDecimal bp = bidding_price_c == null ? new BigDecimal(0) : new BigDecimal(bidding_price_c);
        String sbp = bidding_price_c == null ? "/" : bidding_price_c;

        //推广服务费比例
        String market_commission_rate_c = crmContractData.getString("Market_Commission_Rate_c");
        BigDecimal bigDecimal = new BigDecimal(market_commission_rate_c);
        BigDecimal bp2 = bigDecimal.divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP).multiply(bp);
        // 定稿版补充条款
        String supplementary_c = crmContractData.getString("Supplementary_c");

        String st = supplementary_c == null ? "/" : supplementary_c.replace("<br>", "\r\n");
        if (aName.toString().contains("空-")) {
            aName = new StringBuilder(sales_director_c);
        }
        int aNameLength = aName.length();
        for (int i = 0; i < 6 - aNameLength; i++) {
            aName.append("  ");
        }
        int bNameLength = bName.length();
        for (int i = 0; i < 6 - bNameLength; i++) {
            bName.append("  ");
        }

        //其他服务费比例
        String other_commission_rate_c = crmContractData.getString("Other_Commission_Rate_c");
        // 执行中标价
        String executiveBiddingPrice_c = crmContractData.getString("ExecutiveBiddingPrice_c");
        // 乙方出货价
        String unitPrice_c = crmContractData.getString("UnitPrice_c");
        // 零售价
        String retailPrice_c = crmContractData.getString("RetailPrice_c");

        // 业务签约人身份证号
        String businessContractorIdCard_c = crmContractData.getString("BusinessContractorIdCard_c");
        // 分销最高结算底价
        String maximumDistributionPrice_c = crmContractData.getString("MaximumDistributionPrice_c");
        // 结算低价
        String current_agent_price_c = crmContractData.getString("Current_Agent_Price_c");
        // 缴纳保证金公司名称
        String PayCompany = crmContractData.getString("PayCompany");
        // 省份
        String agent_province_c = crmContractData.getString("Agent_Province_c");
        // 合同编号
        String contractCode_c = crmContractData.getString("ContractCode_c");
        // 实际结算渠道
        String actualRefundPolicy_c = crmContractData.getString("ActualRefundPolicy_c");
        // 应缴市场保证金
        String ocr = other_commission_rate_c == null ? "/" : other_commission_rate_c + "%";
        String ebp = executiveBiddingPrice_c == null ? "/" : executiveBiddingPrice_c;
        String ut = unitPrice_c == null ? "/" : unitPrice_c;

        // 乙方调拨价
        String partyAlloctationPrice_c = crmContractData.getString("PartyBAlloctationPrice_c");
        // 丙方出货价
        String partyCPrice_c = crmContractData.getString("PartyCPrice_c");

        String pbap = partyAlloctationPrice_c == null ? "/" : partyAlloctationPrice_c;
        String pcp = partyCPrice_c == null ? "/" : partyCPrice_c;
        String retailPrice = retailPrice_c == null ? "/" : retailPrice_c;
        String busIdCard = businessContractorIdCard_c == null ? "/" : businessContractorIdCard_c;

        // 推广服务费比例
        String market_commission_rate_c1 = crmContractData.getString("Market_Commission_Rate_c");

        String mcr = market_commission_rate_c1 + "%";
        //C端建议零售价
        String c_end_retail_price_c = crmContractData.getString("C_End_Retail_Price_c");
        String rpbc = c_end_retail_price_c == null ? "/" : c_end_retail_price_c;
        String mdp = maximumDistributionPrice_c == null ? "/" : maximumDistributionPrice_c;

        //支付时间
        String payDate_c = crmContractData.getString("PayDate_c");
        //结算方式
        String settleWay_p_c = crmContractData.getString("SettleWay_P_c");
        //使用方式
        String refundWay_c = crmContractData.getString("RefundWay_c");
        //协议签订公司名称（丙方）
        String newCommercialCompany_c = "";
        JSONObject newCommercialCompany_c1 = crmContractData.getJSONObject("NewCommercialCompany_c");
        if (Objects.nonNull(newCommercialCompany_c1)) {
            newCommercialCompany_c = newCommercialCompany_c1.getString("name");
        }

        // 合同名称
        String contractName = crmContractData.getString("Name");

        StringBuilder data = new StringBuilder("[<甲方名称>]=" + aName
                + "[<乙方名称>]=" + bName
                + "[<丙方名称>]=" + checkString(cName)
                + "[<业务签约人身份证号码>]=" + checkString(busIdCard)
                + "[<产品名称>]=" + checkString(product_name)
                + "[<产品生产厂家>]=" + checkString(manufacturer_c1)
                + "[<产品单位>]=" + checkString(settlementUnit_c)
                + "[<产品中标价>]=" + checkString(sbp)
                + "[<支付时间>]=" + checkString(payDate_c)
                + "[<结款方式>]=" + checkString(settleWay_p_c)
                + "[<推广服务费比例>]=" + checkString(mcr)
                + "[<其他服务费比例>]=" + checkString(ocr)
                + "[<执行中标价>]=" + checkString(ebp)
                + "[<省标价>]=" + bp
                + "[<使用方式>]=" + checkString(refundWay_c)
                + "[<省标价乘推广服务费比例>]=" + bp2.setScale(1, BigDecimal.ROUND_HALF_UP)
                + "[<连锁终端名称>]=" + checkString(newCommercialCompany_c)
                + "[<配送商业公司名单>]=" + checkString(dbcName)
                + "[<目标医院配送商业公司>]=" + checkString(dbcName)
                + "[<乙方出货价>]=" + checkString(ut)
                + "[<乙方调拨价>]=" + checkString(pbap)
                + "[<丙方出货价>]=" + checkString(pcp)
                + "[<产品约定零售价>]=" + checkString(retailPrice)
                + "[<C端建议零售价>]=" + checkString(rpbc)
                + "[<连锁终端推广服务费比例>]=" + market_commission_rate_c1 + "%"
                + "[<连锁终端各项服务费合计>]=" + bp2.setScale(1, BigDecimal.ROUND_HALF_UP)
                + "[<产品的商品名>]=" + checkString(brand_c)
                + "[<产品的件装量>]=" + checkString(unit_c)
                + "[<产品推广结算底价>]=" + checkString(current_agent_price_c)
                + "[<协议起始日期>]=" + checkString(DateUtil.parseDateWord(start_date_c))
                + "[<协议结束日期>]=" + checkString(DateUtil.parseDateWord(end_date_c))
                + "[<推广区域省份>]=" + checkString(agent_province_c)
                + "[<结算底价不高于>]=" + checkString(mdp)
                + "[<补充条款>]=" + checkString(st)
                + "[<甲方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                + "[<乙方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                + "[<缴纳保证金公司名称>]=" + checkString(PayCompany)
                + "[<开发认定标准>]=" + kaifa
                + "[<合同协议编号>]=" + checkString(contractCode_c));

        if ("灵活用工".equals(actualRefundPolicy_c)) {
            String sTitle = "九、推广服务费结算";
            if (models.equals("2024商业分销协议--适用于（商销部）终端协议：分销票折（莫塞）"))
                sTitle = "12.推广服务费结算";
            if (models.equals("2024终端服务协议（开发+上量）--适用于（商销部）终端协议：其他现金"))
                sTitle = "七、推广服务费结算";
            String sconten = "\t乙方可指定两个账号进行费用收取，账户明细如下：\r\n";
            if (caList.size() == 0) {
                sconten += "\t户名1：/\r\n" + "\t卡号1：/\r\n" + "\t开户行1：/\r\n"
                        + "\t户名2：/\r\n" + "\t卡号2：/\r\n" + "\t开户行2：/\r\n";
            }
            if (caList.size() == 1) {
                sconten += "\t户名1：" + caList.get(0).getString("Name") + "\r\n" + "\t卡号1：" + caList.get(0).getString("BankAccount_c") + "\r\n"
                        + "\t开户行1：" + caList.get(0).getString("Bank_c") + "\r\n" + "\t户名2：/\r\n" + "\t卡号2：/\r\n" + "\t开户行2：/\r\n";
            }
            if (caList.size() == 2) {
                sconten += "\t户名1：" + caList.get(0).getString("Name") + "\r\n" + "\t卡号1：" + caList.get(0).getString("BankAccount_c") + "\r\n"
                        + "\t开户行1：" + caList.get(0).getString("Bank_c") + "\r\n" + "\t户名2：" + caList.get(1).getString("Name") + "\r\n"
                        + "\t卡号2：" + caList.get(1).getString("BankAccount_c") + "\r\n" + "\t开户行2：" + caList.get(1).getString("Bank_c") + "\r\n";
            }
            sconten += "甲方通过灵活用工平台将相关款项打入乙方指定账户，乙方为市场服务业务的真实性负责，对向灵活用工平台提供的工作结果负责，且通过甲方审核，否则甲方有权暂停支付。";
            data.append("[<推广服务费结算>]=").append(sTitle).append("[<推广服务费结算内容>]=").append(sconten);
        }

        // 合同目标医院
        System.out.println("处理【合同目标医院】中");

        // 查询合同目标医院开发计划
        List<JSONObject> hdList = BiologicalApiUtil.getHospitalDevelop(zohoRecord.getAccessToken(),contractId);
        Map<String,JSONObject> hdMap = new HashMap<>();
        for (JSONObject hd : hdList) {
            hdMap.put(hd.getJSONObject("Target_Hospital_c").getString("id"),hd);
        }
        if (cthList.size() > 0 && !"商销部".equals(department_c)) {
            data.append("[<目标医院信息名单>]=");
            int time = 1;
            for (JSONObject jsonObject : cthList) {
                // 产品保证金
                String product_security_deposit_c = jsonObject.getString("Product_Sequrity_Deposit_c");
                //执行中标价
                String executivePrice_c = jsonObject.getString("ExecutivePrice_c");
                // 目标医院
                String targetHospitalId = jsonObject.getJSONObject("Target_Hospital_c").getString("id");
                // 目标销量
                String target_quantity_c = hdMap.containsKey(targetHospitalId)?hdMap.get(targetHospitalId).getString("TargetQuantity_c"):"";
                // 开发时限
                String devDeadline_c = hdMap.containsKey(targetHospitalId)?hdMap.get(targetHospitalId).getString("DevelopmentTime_c"):"";

                String psd = product_security_deposit_c == null ? "/" : product_security_deposit_c;
                int psdLength = psd.length();
                StringBuilder psdTemp = new StringBuilder();
                for (int t = 0; t < (16 - psdLength) / 4; t++) {
                    psdTemp.append("\t");
                }
                // 执行中标价
                String ep = executivePrice_c == null ? "/" : executivePrice_c;
                int epLength = ep.length();
                StringBuilder epTemp = new StringBuilder("\t\t");
                for (int t = 0; t < (9 - epLength) / 4; t++) {
                    epTemp.append("\t");
                }
                String dev = devDeadline_c == null ? "/\t\t" : devDeadline_c;
                String target_hospital_c = jsonObject.getString("HospitalList_c");
                // 目标医院名称
                if (StringUtils.isNotBlank(target_hospital_c)) {
                    String hName = target_hospital_c.replace("（", "(").replace("）", ")");
                    String qname = "";
                    if (hName.length() >= 20) {
                        String pName = hName.substring(0, 20);
                        qname = hName.substring(20);
                        String nameTemp = getTemp(pName, 52);
                        data.append(pName).append(nameTemp);
                    }
                    if (hName.length() < 20) {
                        String nameTemp = getTemp(hName, 52);
                        data.append(hName).append(nameTemp);
                    }
                    data.append(dev).append("\t").append(psd).append(psdTemp).append(ep).append(epTemp)
                            .append(market_commission_rate_c1).append("%\t\t").append(ocr).append("\r\n");
                    if (hName.length() >= 20) {
                        data.append(qname).append("\r\n");
                    }
                }
            }
        }
        if (cthList.size() > 0 && "商销部".equals(department_c)) {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < cthList.size(); i++) {
                //System.out.println("处理条数 = " + (i + 1));
                String hName = "";
                String nameTemp = "";
                // 目标医院

                String target_hospital_c = cthList.get(i).getString("HospitalList_c");

                if (StringUtils.isNotBlank(target_hospital_c)) {
                    hName = target_hospital_c.replace("（", "(").replace("）", ")");
                    nameTemp = getTemp(hName, 52);

                    // 机构性质
                    String institutional_c = cthList.get(i).getString("Institutional_c");
                    String institutional = institutional_c == null ? "/\t\t" : institutional_c + "\t";


                    // 合同目标医院 -> 目标医院 -> 合同目标医院开发计划
                    boolean isKFJH = false; // 是否有开发计划
                    JSONObject jsonObject = cthList.get(i);
                    String targetHospitalId = jsonObject.getJSONObject("Target_Hospital_c").getString("id");// 目标医院
                    // 目标销量
                    String target_quantity_c = hdMap.containsKey(targetHospitalId)?hdMap.get(targetHospitalId).getString("TargetQuantity_c"):"";
                    // 开发时限
                    String devDeadline_c = hdMap.containsKey(targetHospitalId)?hdMap.get(targetHospitalId).getString("DevelopmentTime_c"):"";

                    String targetQuantity = target_quantity_c == null ? "/" : target_quantity_c;

                    // 开发时间
                    //String dd = devDeadline_c == null ? "\t/\t" : devDeadline_c;
                    String dev = devDeadline_c == null ? "\t/\t" : devDeadline_c;
                    // 分值
                    String hospital_integral_c = checkString(cthList.get(i).getString("Hospital_Integral_c"));
                    // 开发状态
                    String hospital_status_c = checkString(cthList.get(i).getString("Hospital_Status_c"));

                    String dev2 = hospital_status_c.contains("已开发") ? hospital_status_c : dev;
                    if (!isKFJH) {
                        dev2 = hospital_status_c;
                    }

                    builder.append(i + 1).append("\t")
                            .append(hName).append(nameTemp)
                            .append(institutional).append("\t");//机构性质

                    // 目标医院 id
                    thIdList.add(cthList.get(i).getString("id"));
                }


            }
            data.append("[<目标医院名单>]=").append(builder);
        } else {
            data.append("[<目标医院名单>]=/");
        }
        System.out.println("处理【合同目标医院】结束");
        // 遍历 销售指标
        System.out.println("处理【销售指标】中...");
        // 查询销售指标
        List<JSONObject> dpList = BiologicalApiUtil.getSaleTarget(zohoRecord.getAccessToken(), contractId);
        if (dpList.size() > 0) {
            // 正序排序
            dpList.sort(Comparator.comparingInt(x -> Integer.parseInt(x.getString("Year_c")) + Integer.parseInt(x.getString("Month_c"))));
            BigDecimal ds = new BigDecimal(0);
            data.append("[<销售指标>]=");
            int time = 1;
            for (JSONObject dp : dpList) {
                //System.out.println("处理条数 = " + time++);
                // 年
                String year_c = dp.getString("Year_c");
                // 月
                String month_c = dp.getString("Month_c");
                // 销售指标
                String target_c = dp.getString("Target_c");
                data.append(checkString(year_c)).append("年")
                        .append(checkString(month_c)).append("月")
                        .append("\t\t\t\t\t\t\t").append(checkString(target_c)).append("\r\n");
                BigDecimal num;
                if (StringUtils.isBlank(target_c)) {
                    num = new BigDecimal(0);
                } else {
                    num = new BigDecimal(target_c);
                }

                ds = ds.add(num);
            }
            data.append("[<销售指标合计>]=").append(ds);
        } else {
            data.append("[<销售指标>]=/");
            data.append("[<销售指标合计>]=/");
        }
        System.out.println("处理【销售指标】结束");

        // 查询合同开发指标
        List<JSONObject> cdliList = BiologicalApiUtil.getDevelopTarget(zohoRecord.getAccessToken(), contractId);

        // 遍历 开发指标

        System.out.println("处理【开发指标】中...");
        if (cdliList.size() > 0) {
            // 正序排序
            cdliList.sort(Comparator.comparingInt(x -> Integer.parseInt(x.getString("Year_c")) + Integer.parseInt(x.getString("Month_c"))));

            BigDecimal ds = new BigDecimal(0);
            data.append("[<开发指标>]=");
            int time = 1;
            for (JSONObject cd : cdliList) {
                // 年
                String year_c = cd.getString("Year_c");
                // 月
                String month_c = cd.getString("Month_c");
                // 开发指标
                String developmentIndex_c = cd.getString("DevelopmentIndex_c");
                data.append(checkString(year_c)).append("年")
                        .append(checkString(month_c)).append("月")
                        .append("\t\t\t\t\t\t\t").append(checkString(developmentIndex_c)).append("\r\n");
                BigDecimal num = new BigDecimal(developmentIndex_c);
                ds = ds.add(num);
            }
            data.append("[<开发指标合计>]=").append(ds);
        } else {
            data.append("[<开发指标>]=/");
            data.append("[<开发指标合计>]=/");
        }
        System.out.println("处理【开发指标】结束");

        // 遍历 合同目标医院
        System.out.println("处理【合同目标医院】中...");
        if (models.equals("2024商业分销协议--适用于（商销部）终端协议：分销票折（莫塞）")
                || models.equals("2024终端服务协议（开发+上量）--适用于（商销部）终端协议：其他现金")
                || models.equals("2024终端服务协议（开发+上量）--模板--v1.0适用于省代模式(乐萌、文奥、立优为)")
                || models.equals("2024终端服务协议（开发+上量）--模板--v1.0适用于医院代理(乐萌、文奥、立优为)")
        ) {
            if (cthList.size() > 0) {
                String thsd = "";
                int index = 1;
                for (int i = 0; i < cthList.size(); i++) {
                    //System.out.println("处理条数 = " + (i + 1));
                    // 机构性质
                    String institutional_c = cthList.get(i).getString("Institutional_c");
                    String institutional = institutional_c == null ? "/\t\t" : institutional_c + "\t";

                    // 目标销量
                    String target_quantity_c = cthList.get(i).getString("Target_Quantity_c");
                    String targetQuantity = target_quantity_c == null ? "/" : target_quantity_c;
                    // 分值
                    String hospital_integral_c = checkString(cthList.get(i).getString("Hospital_Integral_c"));
                    // 开发状态
                    String hospital_status_c = checkString(cthList.get(i).getString("Hospital_Status_c"));

                    // 目标医院
                    String target_hospital_c = cthList.get(i).getString("HospitalList_c");

                    if (StringUtils.isNotBlank(target_hospital_c)) {
                        String hname = target_hospital_c.replace("（", "(").replace("）", ")");
                        String nametemp = getTemp(hname, 52);

                        thsd += index++ + "\t"
                                + hname + nametemp
                                + institutional + "\t\t"        //机构性质
                                + checkString(hospital_integral_c) + "\t\t"  //分值
                                + targetQuantity + "\t"         // 目标销量
                                + checkString(hospital_status_c) + "\r\n";   //开发状态

                        // 目标医院 id
                        thIdList.add(cthList.get(i).getString("id"));
                    }
                }
                data.append("[<目标医院名单>]=").append(thsd);
            } else {
                data.append("[<目标医院名单>]=/");
            }
        }
        System.out.println("处理【合同目标医院】结束");

        System.out.println("处理【目标医院销售指标】中...");
        if (thisList.size() > 0) {
            Map<String, Object> thMap = new HashMap<>();
            Map<String, Object> thsiYearMap = new HashMap<>();
            Map<String, Object> thsiYearYearMap = new HashMap<>();
            Map<String, Object> thsiYearMonthMap = new HashMap<>();
            int time = 1;
            for (JSONObject thsi : thisList) {
                //System.out.println("处理条数 = " + time++);
                //System.out.println("thsi.toJSONString() = " + thsi.toJSONString());
                // 目标医院id
                String targetId = thsi.getJSONObject("Target_HospitalF_c").getString("id");
//                List<JSONObject> targetHospital1 = BiologicalApiUtil.getTargetHospital(zohoRecord.getAccessToken(), targetId);
                name = cthMap.get(targetId).getString("HospitalList_c");
                String year = thsi.getString("Year_c");
                String month = thsi.getString("Month_c");
                String target_sales_c = thsi.getString("Target_sales_c");
                JSONObject target_hospitalF_c = thsi.getJSONObject("Target_HospitalF_c");
                String id = target_hospitalF_c.getString("id");
//                List<JSONObject> targetHospital = BiologicalApiUtil.getTargetHospital(zohoRecord.getAccessToken(), id);
//                JSONObject target_hospital_c = targetHospital.get(0);                // 分值
                String hospital__c = cthMap.get(targetId).getString("Hospital_Integral_c");
                // 目标医院+年-分值
                thMap.put(name + year, hospital__c);
                // 目标医院+年-目标医院名称
                thsiYearMap.put(name + year, name);
                // 目标医院+年-年
                thsiYearYearMap.put(name + year, year);
                // 目标医院+年+月-销售指标
                //String ym = name + year + Integer.valueOf(month);
                thsiYearMonthMap.put(name + year + Integer.valueOf(month), target_sales_c);

            }
            BigDecimal cs = new BigDecimal(0);
            BigDecimal s1 = new BigDecimal(0);
            BigDecimal s2 = new BigDecimal(0);
            BigDecimal s3 = new BigDecimal(0);
            BigDecimal s4 = new BigDecimal(0);
            BigDecimal s5 = new BigDecimal(0);
            BigDecimal s6 = new BigDecimal(0);
            BigDecimal s7 = new BigDecimal(0);
            BigDecimal s8 = new BigDecimal(0);
            BigDecimal s9 = new BigDecimal(0);
            BigDecimal s10 = new BigDecimal(0);
            BigDecimal s11 = new BigDecimal(0);
            BigDecimal s12 = new BigDecimal(0);
            BigDecimal ss = new BigDecimal(0); // 总合计
            data.append("[<医院销售指标名单>]=");
            Set<String> set = thsiYearMap.keySet();
            List<String> keyList = new ArrayList<>(set);
            for (String s : keyList) {
                //System.out.println("s = " + s);
                // 每月指标合计
                cs = getBigDecimal(cs, thMap.get(s));
                s1 = getBigDecimal(s1, thsiYearMonthMap.get(s + "1") == null ? 0 : thsiYearMonthMap.get(s + "1"));
                s2 = getBigDecimal(s2, thsiYearMonthMap.get(s + "2") == null ? 0 : thsiYearMonthMap.get(s + "2"));
                s3 = getBigDecimal(s3, thsiYearMonthMap.get(s + "3") == null ? 0 : thsiYearMonthMap.get(s + "3"));
                s4 = getBigDecimal(s4, thsiYearMonthMap.get(s + "4") == null ? 0 : thsiYearMonthMap.get(s + "4"));
                s5 = getBigDecimal(s5, thsiYearMonthMap.get(s + "5") == null ? 0 : thsiYearMonthMap.get(s + "5"));
                s6 = getBigDecimal(s6, thsiYearMonthMap.get(s + "6") == null ? 0 : thsiYearMonthMap.get(s + "6"));
                s7 = getBigDecimal(s7, thsiYearMonthMap.get(s + "7") == null ? 0 : thsiYearMonthMap.get(s + "7"));
                s8 = getBigDecimal(s8, thsiYearMonthMap.get(s + "8") == null ? 0 : thsiYearMonthMap.get(s + "8"));
                s9 = getBigDecimal(s9, thsiYearMonthMap.get(s + "9") == null ? 0 : thsiYearMonthMap.get(s + "9"));
                s10 = getBigDecimal(s10, thsiYearMonthMap.get(s + "10") == null ? 0 : thsiYearMonthMap.get(s + "10"));
                s11 = getBigDecimal(s11, thsiYearMonthMap.get(s + "11") == null ? 0 : thsiYearMonthMap.get(s + "11"));
                s12 = getBigDecimal(s12, thsiYearMonthMap.get(s + "12") == null ? 0 : thsiYearMonthMap.get(s + "12"));

                BigDecimal sum = new BigDecimal(0);
                // 计算总合计
                for (int sm = 1; sm <= 12; sm++) {
                    if (thsiYearMonthMap.get(s + sm) != null) {
                        String num = thsiYearMonthMap.get(s + sm).toString();
                        sum = getBigDecimal(sum, num);
                    }
                }
                ss = ss.add(sum);

                StringBuilder dataMonth = new StringBuilder();
                for (Integer m = 1; m <= 12; m++) {
                    if (thsiYearMonthMap.get(s + m) == null) {
                        dataMonth.append(m).append("月：/\t");
                    } else {
                        dataMonth.append(m).append("月：").append(thsiYearMonthMap.get(s + m)).append("\t");
                    }
                }
                String hName = thsiYearMap.get(s).toString().replace("(", "（").replace(")", "）");
                String nameTemp = getTemp(hName, 34);
                data.append("医院名称：").append(hName).append(nameTemp // 目标医院名称
                ).append("医院分值：").append(thMap.get(s)).append(" \t" // 分值
                ).append("年份：").append(thsiYearYearMap.get(s)).append("  \t\r\n" // 年
                ).append(dataMonth).append("合计：").append(sum).append("\r\n");
            }
            data.append("合计：\r\n" + " 1月：").append(s1).append("\t").append(" 2月：").append(s2).append("\t").append(" 3月：").append(s3).append("\t")
                    .append(" 4月：").append(s4).append("\t").append(" 5月：").append(s5).append("\t").append(" 6月：").append(s6).append("\t")
                    .append(" 7月：").append(s7).append("\t").append(" 8月：").append(s8).append("\t").append(" 9月：").append(s9).append("\t")
                    .append("10月：").append(s10).append("\t").append("11月：").append(s11).append("\t").append("12月：").append(s12).append("\t")
                    .append("总合计：").append(ss);
        } else {
            data.append("[<医院销售指标名单>]=以下空白");
        }
        System.out.println("处理【目标医院销售指标】结束");

        String jsonStu = getJsonStu(models, data);
        String url = "";
        String fileRtn = "0";
        try {
            url = "http://" + tokenMap.get("httpServerIP") + ":" +
                    tokenMap.get("httpPort") + "/?Op=" + op +
                    "&ZTIdx=" + tokenMap.get("zTIdx") +
                    "&Token=" + tokenMap.get("token")
                    + "&APIClass=" + aPIClass + "&FileRtn=" + fileRtn;
        } catch (Exception e) {
            log.error(" e:" + e);
        }
        //System.out.println("url = " + url);
        //System.out.println("jsonStu = " + jsonStu);
        Map<String, Object> resMap = HttpUtil.postJsonData(url, jsonStu);

        if (checkResponseMap(resMap)) return ResultUtil.error("请求接口不通！");
        String workIDs = resMap.get("WorkIDs").toString();
        log.info("workIDs=" + workIDs);

        // 第三步 获取downFiles
        List<String> downFiles = getDownFiles(workIDs, tokenMap);

        // 第四步 生成文件
        // 模板增加乙方名称
        contractName = bName + "_" + contractName;
        generatorFile(downFiles, tokenMap, contractId, contractName);

        // 删除之前缓存的文件
        deleteFile();
        return ResultUtil.success();
    }

    public String getTemp(String str, Integer threshold) {
        Integer len = str.length();
        String regEx = "[\\u4e00-\\u9fa5]";
        Integer count = 0;
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        while (m.find()) {
            for (int i = 0; i <= m.groupCount(); i++) {
                count = count + 1;
            }
        }
        // 剩余可用宽度
        int dividend = threshold - len - count;
        BigDecimal bigDecimal = new BigDecimal(dividend);
        BigDecimal resultDecimal = bigDecimal.divide(new BigDecimal(4));
        Integer resultDown = resultDecimal.setScale(0, BigDecimal.ROUND_DOWN).intValue();
        // 是否是4的倍数 用来计算\t 个数
        int c = dividend - resultDown * 4;
        int ti = c > 2 ? dividend / 4 + 1 : dividend / 4;
        StringBuilder temp = new StringBuilder(" ");
        if (ti > 0) {
            if (ti > 1 && str.contains("(")) ti--;
            for (int i = 0; i < ti; i++) {
                temp.append("\t");
            }
        }
        return temp.toString();
    }


    public String getJsonStu(String models, StringBuilder data) {
        String JSONStu = "{";
        JSONStu += "\"Models\":\"" + models + "\",";
        JSONStu += "\"Data\":\"" + data + "\"}";
        //log.info("JSONStu = " + JSONStu);
        return JSONStu;
    }

    public Map<String, String> getStartAndEndTime(String start_date_c, String end_date_c) {
        HashMap<String, String> map = new HashMap<>();
        String startDate = DateUtil.getFirstDayOfMonth(DateUtil.stringParseDate(start_date_c));
        String endDate = DateUtil.getLastDayOfMonth(DateUtil.stringParseDate(end_date_c));
        map.put("startDate", startDate);
        map.put("endDate", endDate);
        return map;
    }

    @Override
    public void generatorFile() {
        //System.out.println("zohoRecord.getAccessToken() = " + zohoRecord.getAccessToken());
        //String startFile = "D:\\testWord.docx";
        //
        //System.out.println("准备将文件传送至CRM");
        ////        文件流方式
        //String url = "https://www.zohoapis.com.cn/crm/v3/Contract/" + "199864000001372464" + "/Attachments";
        //JSONObject jsonObject = HttpUtil.postFileByStream(zohoRecord.getAccessToken(), startFile, url);
        //System.out.println("jsonObject.toJSONString() = " + jsonObject.toJSONString());


    }

    public void deleteFile() {
        log.info("===== 第五步【删除缓存文件】 =====");
        // 1 获取所有文件
        List<File> allFile = FileUtil.getAllFile();
        for (File file : allFile) {
            String name = file.getName();
            if (name.contains(".doc")) {
                if (file.delete()) {
                    log.info(name + " ——> 已经删除");
                }
            }
        }
    }

    //判断当前整数部分是否已经是达到【万】
    private static boolean isWan5(String integerStr) {
        int length = integerStr.length();
        if (length > 4) {
            String subInteger;
            if (length > 8) {
                subInteger = integerStr.substring(length - 8, length - 4);
            } else {
                subInteger = integerStr.substring(0, length - 4);
            }
            return Integer.parseInt(subInteger) > 0;
        } else {
            return false;
        }
    }

    //将小数部分转为大写的金额
    private static String getChineseDecimal(Integer[] decimals) {
        String[] NUMBERS = new String[]{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
        String[] DUNIT = new String[]{"角", "分", "厘"};
        StringBuilder chineseDecimal = new StringBuilder();
        for (int i = 0; i < decimals.length; i++) {
            if (i == 3) {
                break;
            }
            chineseDecimal.append(decimals[i] == 0 ? "" : (NUMBERS[decimals[i]] + DUNIT[i]));
        }
        return chineseDecimal.toString();
    }

    //将整数部分转为大写的金额
    public static String getChineseInteger(Integer[] integers, boolean isWan) {
        String[] NUMBERS = new String[]{"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
        String[] UNIT = new String[]{"元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟"};
        StringBuilder chineseInteger = new StringBuilder();
        Integer length = integers.length;
        if (length == 1 && integers[0] == 0) {
            return "";
        }
        for (Integer i = 0; i < length; i++) {
            String key = "";
            if (integers[i] == 0) {
                if ((length - i) == 13)//万（亿）
                    key = UNIT[4];
                else if ((length - i) == 9) {//亿
                    key = UNIT[8];
                } else if ((length - i) == 5 && isWan) {//万
                    key = UNIT[4];
                } else if ((length - i) == 1) {//元
                    key = UNIT[0];
                }
                if ((length - i) > 1 && integers[i + 1] != 0) {
                    key += NUMBERS[0];
                }
            }
            chineseInteger.append(integers[i] == 0 ? key : (NUMBERS[integers[i]] + UNIT[length - i - 1]));
        }
        return chineseInteger.toString();
    }

    //转成中文的大写金额
    public static String toChinese(String str) {
        if ("0".equals(str) || "0.00".equals(str) || "0.0".equals(str)
                || "0.000".equals(str) || "0.0000".equals(str) || str == null) {
            return "零元";
        }
        boolean flag = false;
        if (str.startsWith("-")) {
            flag = true;
            str = str.replaceAll("-", "");
        }
        str = str.replaceAll(",", "");//去掉","
        String integerStr;//整数部分数字
        String decimalStr;//小数部分数字
        //初始化：分离整数部分和小数部分
        if (str.indexOf(".") > 0) {
            integerStr = str.substring(0, str.indexOf("."));
            decimalStr = str.substring(str.indexOf(".") + 1);
        } else if (str.indexOf(".") == 0) {
            integerStr = "";
            decimalStr = str.substring(1);
        } else {
            integerStr = str;
            decimalStr = "";
        }

        Integer[] integers = toIntArray2(integerStr);//整数部分数字
        //判断整数部分是否存在输入012的情况
        if (integers.length > 1 && integers[0] == 0) {
            return str;
        }
        boolean isWan = isWan5(integerStr);//设置万单位
        Integer[] decimals = toIntArray2(decimalStr);//小数部分数字
        String result = getChineseInteger(integers, isWan) + getChineseDecimal(decimals);//返回最终的大写金额
        if (flag) {
            return "负" + result;//如果是负数，加上"负"
        } else {
            return result;
        }
    }

    //将字符串转为int数组
    public static Integer[] toIntArray2(String number2) {
        Integer[] array2 = new Integer[number2.length()];
        for (int i = 0; i < number2.length(); i++) {
            array2[i] = Integer.valueOf(number2.substring(i, i + 1));
        }
        return array2;
    }

    @Async("asyncPoolTaskExecutor")
    @SneakyThrows
    @Override
    public ResultUtil<String> marketContractTemplate(String contractId, String operationId) {
        log.info("contractId = {},operationId = {}", contractId, operationId);
        if (StringUtils.isBlank(contractId) || StringUtils.isBlank(operationId)) {
            return ResultUtil.error("入参为空");
        }
        ResultUtil<String> result = ResultUtil.success();

        log.info("2022市场营销服务协议");
        // 1 校验条件，当前操作人
        boolean isCheck = false;
        List<JSONObject> userData = CrmApiUtil.getUserDataById(zohoRecord.getAccessToken(), operationId);
        if (!CollectionUtils.isEmpty(userData)) {
            JSONObject user = userData.get(0);
            JSONObject profile = user.getJSONObject("profile");
            if (Objects.nonNull(profile)) {
                String roleName = profile.getString("name");
                log.info("当前用户角色名称：" + roleName);
                if (roleName.equalsIgnoreCase("客服助理") ||
                        roleName.equalsIgnoreCase("发货组客服组长") ||
                        roleName.equalsIgnoreCase("购销服务部经理") ||
                        roleName.equalsIgnoreCase("系统管理员") ||
                        roleName.equalsIgnoreCase("Administrator")) {
                    isCheck = true;
                }
            }
        }

        if (isCheck) {
            // 2 获取token
            Map<String, Object> tokenMap = getToken();
            if (tokenMap.containsKey("ERROR")) {
                return ResultUtil.error((String) tokenMap.get("ERROR"));
            }
            // 3 过滤合同数据，根据id循环调试，是否生成文件，获取文件流
            result = filterContractData(contractId, tokenMap, 2);
        }
        return result;
    }


    // 2022市场营销服务协议 过滤
    public ResultUtil<String> provincialGeneration2022(String contractId, JSONObject crmContractData, Map<String, Object> tokenMap) {
        //布局
        JSONObject layout = crmContractData.getJSONObject("Layout");
        String name = layout.getString("name");
        // 查询合同目标医院
        List<JSONObject> cthList = new ArrayList<>();
        if ("市场推广服务协议".equalsIgnoreCase(name) || "终端协议".equalsIgnoreCase(name)) {
            cthList = BiologicalApiUtil.getContractTargetHospital(zohoRecord.getAccessToken(),contractId);
//            cthList = bUtils.getContractTargetHospital(zohoRecord.getAccessToken(), contractId);
        }

        Map<String, String> cspMap = new HashMap<>();
        // 服务商准入
        List<JSONObject> cspList = BiologicalApiUtil.getServiceAccess(zohoRecord.getAccessToken(), contractId);
        for (JSONObject jsonObject : cspList) {
            // 准入公司名字
            String accessCompany_c = jsonObject.getString("AccessCompany_c");
            // 准入公司法人
            String field1 = jsonObject.getString("AccessOwner_c");
            cspMap.put(accessCompany_c, field1);
        }
        // 协议开始日期
        String start_date_c = crmContractData.getString("Start_Date_c");
        // 协议结束日期
        String end_date_c = crmContractData.getString("End_Date_c");
        // 省份
        String agent_province_c = crmContractData.getString("Agent_Province_c");
        // 合同编号
        String contractCode_c = crmContractData.getString("ContractCode_c");
        // 实际结算渠道
        String actualRefundPolicy_c = crmContractData.getString("ActualRefundPolicy_c");
        //推广性质
        String agent_style_c = crmContractData.getString("Agent_Stlye_c");
        //填表人所属部门
        String department_c = crmContractData.getString("Department_c");

        // 客户/业务签约人
        String agentName = "";
        JSONObject agents_c = crmContractData.getJSONObject("Agents_c");
        if (Objects.nonNull(agents_c)) {
            agentName = agents_c.getString("name");
        }
        // 合同所有者
        JSONObject owner = crmContractData.getJSONObject("shareuser");
        String ownerName = "";
        if (Objects.nonNull(owner)) {
            ownerName = owner.getString("name");
        }
        //市场营销服务协议公司名称
        String serviceCompany_c = crmContractData.getString("ServiceCompany_c");
        // 结算主体
        String paySubject_c = crmContractData.getString("PaySubject_c");
        //实缴保证金合计
        String total_paid_deposit_c = crmContractData.getString("Total_paid_deposit_c");
        // 应缴产品保证金
        String product_deposit_payable_c = crmContractData.getString("Product_deposit_payable_c");
        // 应缴市场保证金
        String market_margin_payable_c = crmContractData.getString("Market_margin_payable_c");
        // 应缴保证金合计
        String total_deposit_payable_c = crmContractData.getString("Total_deposit_payable_c");
        // 推广服务费比例
        String market_commission_rate_c = crmContractData.getString("Market_Commission_Rate_c");
        // 结算低价
        String current_agent_price_c = crmContractData.getString("Current_Agent_Price_c");
        String isIsProvinceRate = "省级代理".equals(agent_style_c) ? "是" : "否";
        // 结算方式
        String actualRefundPolicy = actualRefundPolicy_c + "%";

        // 推广产品（包装包材）
        JSONObject agent_product_package_c = crmContractData.getJSONObject("Agent_Product_Package_c");
        String packageId = "";
        // 结算单位
        String settlementUnit_c = "";
        if (Objects.nonNull(agent_product_package_c)) {
            packageId = agent_product_package_c.getString("id");
        }
        // 合同名称
        String contractName = crmContractData.getString("Name");
        // 商品名/ 商标名
        String brand_c = "";
        // 产品名称
        String product_name = "";
        // 生产企业
        String manufacturer_c = "";
        if (!"".equals(packageId)) {
            List<JSONObject> packingMaterial = BiologicalApiUtil.getPackingMaterialByProduct(zohoRecord.getAccessToken(), packageId);
            if (!CollectionUtils.isEmpty(packingMaterial)) {
                JSONObject jsonObject = packingMaterial.get(0);
                brand_c = jsonObject.getString("Brand_c");
                product_name = jsonObject.getString("Name");
                settlementUnit_c = jsonObject.getString("SettlementUnit_c");
                manufacturer_c = jsonObject.getString("Manufacturer_c");
                paySubject_c = jsonObject.getString("Supplier_c");
            }
        }

        // 产品包装(包材)
        String product_wrapper_c = crmContractData.getString("Product_Wrapper_c");
        // 申请结算渠道
        String applicationRefundPolicy_c = crmContractData.getString("ApplicationRefundPolicy_c");
        // 高开返款税率表主政策
        List<JSONObject> hrmtrList = new ArrayList<>();
        List<JSONObject> hrmtrListTemp = BiologicalApiUtil.getTHighTax(zohoRecord.getAccessToken(), isIsProvinceRate, product_wrapper_c);

        // 过滤数据
        for (JSONObject jsonObject : hrmtrListTemp) {
            // 记录类型
            String recordType = jsonObject.getString("RecordType");
            // 结算方式
            String refundPolicy_c1 = jsonObject.getString("RefundPolicy_c");
            if (recordType.equals("代管商业") && refundPolicy_c1.contains(actualRefundPolicy)) {
                hrmtrList.add(jsonObject);
            }
        }

        String serviceCompany = cspMap.keySet().size() > 0 ? cspMap.keySet().toArray(new String[0])[0] : "";
        String bName = cspMap.getOrDefault(serviceCompany, "/");
        String op = "21";
        String aPIClass = "TGFWXY004";
        String models = "";
        String fileRtn = "0";
        String sd = total_deposit_payable_c;
        String appliedTicketPrice_c = "/";
        StringBuilder detailData1 = new StringBuilder();
        if ("市场推广服务协议".equalsIgnoreCase(name) || "终端协议".equalsIgnoreCase(name)) {
            appliedTicketPrice_c = current_agent_price_c;
            detailData1.append("\"DetailData1\":[");
            detailData1.append("{\"RowData\":\"")
                    .append("[<T1>]=").append(product_name)
                    .append("[<T2>]=").append(brand_c)
                    .append("[<T3>]=").append(settlementUnit_c)
                    .append("[<T4>]=").append(manufacturer_c)
                    .append("[<T5>]=").append(appliedTicketPrice_c+"元").append("\"}");

            detailData1.append(",{\"RowData\":\"[<T1>]=以下空白\"}");
            detailData1.append("],");
            serviceCompany = crmContractData.getString("PayCompany");
            // 查询合同配送商业公司
//            List<JSONObject> cdcList = BiologicalApiUtil.getBusinessCompany(zohoRecord.getAccessToken(), contractId);
//            if (cdcList.size() > 0) {
//                for (int i = 0; i < cdcList.size(); i++) {
//                    // 商业公司
//                    JSONObject businessCompany_c1 = cdcList.get(i).getJSONObject("BusinessCompany_c");
//                    if (Objects.nonNull(businessCompany_c1)) {
//                        serviceCompany = businessCompany_c1.getString("name");
//                    }
//                }
//            }

            if (applicationRefundPolicy_c.equalsIgnoreCase("CSO")
                    || applicationRefundPolicy_c.equalsIgnoreCase("灵活用工")) {
                models = "2025推广服务协议（CSO模板-国为体系）";
            }
            if (applicationRefundPolicy_c.equalsIgnoreCase("底价")) {
                if (department_c.contains("一部")) {
                    models = "2025经销推广配送协议一部";
                }
                if (department_c.contains("二部")) {
                    models = "2025经销推广配送协议二部";
                }
                if (department_c.contains("商销部")) {
                    models = "2025经销推广配送协议商销部";
                }
            }
        }

        if ("商业经销协议".equalsIgnoreCase(name) || "经销推广协议".equals(name)) {
            models = "2025经销推广配送协议商销部";
            serviceCompany = agentName;
            // 查询配送产品
            List<JSONObject> ccList = BiologicalApiUtil.getDistributionProduct(zohoRecord.getAccessToken(), contractId);
            detailData1.append("\"DetailData1\":[");
            for (int i=0; i<ccList.size();i++) {
                JSONObject jsonObject = ccList.get(i);
                JSONObject product_delivery_c = jsonObject.getJSONObject("Product_Delivery_c");
                String id = product_delivery_c.getString("id"); // 包装包材id
                // 申请开票价
                appliedTicketPrice_c = jsonObject.getString("AppliedTicketPrice_c");
                List<JSONObject> packingMaterialByProduct = BiologicalApiUtil.getPackingMaterialByProduct(zohoRecord.getAccessToken(), id);
                if (packingMaterialByProduct.size() > 0) {
                    String supplier_c = packingMaterialByProduct.get(0).getString("Supplier_c");
                    // 供货方
                    paySubject_c = supplier_c;
                    // 产品名称
                    product_name = packingMaterialByProduct.get(0).getString("Name");
                    // 商标名
                    brand_c = packingMaterialByProduct.get(0).getString("Brand_c");
                    // 结算单位
                    settlementUnit_c = packingMaterialByProduct.get(0).getString("SettlementUnit_c");
                    // 生成企业
                    manufacturer_c = packingMaterialByProduct.get(0).getString("Manufacturer_c");

                    detailData1.append("{\"RowData\":\"")
                            .append("[<T1>]=").append(product_name)
                            .append("[<T2>]=").append(brand_c)
                            .append("[<T3>]=").append(settlementUnit_c)
                            .append("[<T4>]=").append(manufacturer_c)
                            .append("[<T5>]=").append(appliedTicketPrice_c+"元").append("\"}");
                    if(i<ccList.size() - 1) {
                        detailData1.append(",");
                    }else{
                        detailData1.append(",{\"RowData\":\"[<T1>]=以下空白\"}");
                    }
                }
            }
            detailData1.append("],");
        }

        String serviceNumber = "";
        if ("市场推广服务协议".equalsIgnoreCase(name)) {
            String serviceNumberX = hrmtrList.size() > 0 ? String.valueOf(hrmtrList.get(0).getString("TaxRate_c")) : "0";
            serviceNumber = "(开票价-核算价)*(1-" + serviceNumberX + "%)";
        }
        if ("终端协议".equalsIgnoreCase(name)) {
            String mcr = String.valueOf(market_commission_rate_c);
            serviceNumber = "中标价*" + mcr + "%";
        }
        // 定稿版补充条款
        String supplementary_c = crmContractData.getString("Supplementary_c");
        String st = supplementary_c == null ? "无" : supplementary_c.replace("<br>", "\r\n");

        StringBuilder data = new StringBuilder("[<甲方名称>]=" + paySubject_c
                + "[<乙方名称>]=" + bName
                + "[<公司名称>]=" + checkString(serviceCompany)
                + "[<所有人名称>]=" + checkString(ownerName)
                + "[<初始保证金>]=" + checkString(sd)
                + "[<初始保证金大写>]=" + toChinese(sd)
                + "[<产品名称规格>]=" + checkString(product_name)
                + "[<产品名称以及规格>]=" + checkString(product_name)
                + "[<产品的商品名>]=" + checkString(brand_c)
                + "[<产品单位>]=" + checkString(settlementUnit_c)
                + "[<产品生产厂家>]=" + checkString(manufacturer_c)
                + "[<协议起始日期>]=" + checkString(DateUtil.parseDateWord(start_date_c))
                + "[<协议结束日期>]=" + checkString(DateUtil.parseDateWord(end_date_c))
                + "[<省份>]=" + checkString(agent_province_c)
                + "[<甲方供货价>]=" + checkString(appliedTicketPrice_c) + "元"
                + "[<推广区域省份>]=" + checkString(agent_province_c)
                + "[<甲方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                + "[<乙方签订年月日>]=" + DateUtil.dateParseStringWord(new Date())
                + "[<补充条款>]=" + checkString(st)
                + "[<合同协议编号>]=" + checkString(contractCode_c));

        StringBuilder JSONStu = new StringBuilder("{");
        JSONStu.append("\"Models\":\"").append(models).append("\",");
        JSONStu.append(detailData1);
        // 合同目标医院id 查询 目标医院id
        Set<String> thIdList = cthList.stream().map(json -> json.getJSONObject("Target_Hospital_c").getString("id")).collect(Collectors.toSet());
        List<String> thIdListData = new ArrayList<>(thIdList);
        int limit = 50;
        // 遍历 合同目标医院
        System.out.println("处理【合同目标医院】中...");
        if (cthList.size() > 0) {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < cthList.size(); i++) {
                //System.out.println("处理条数 = " + (i + 1));
                String hName = "";
                String nameTemp = "";
                // 目标医院
                JSONObject target_hospital_c1 = cthList.get(i).getJSONObject("Target_Hospital_c");
                hName = target_hospital_c1.getString("name").split("-")[0];
//                hName = cthList.get(i).getString("HospitalList_c").replace("（", "(").replace("）", ")");
                nameTemp = getTemp(hName, 42);
                // 开发时间
                String devDeadline_c = cthList.get(i).getString("DevDeadline_c");
                //String dd = devDeadline_c == null ? "/" : devDeadline_c;
                String dev = devDeadline_c == null ? "\t/\t" : devDeadline_c;
                // 分值
                String hospital_integral_c = cthList.get(i).getString("Hospital_Integral_c");
                // 开发状态
                String hospital_status_c = checkString(cthList.get(i).getString("Hospital_Status_c"));
                String dev2 = hospital_status_c.contains("已开发") ? hospital_status_c : dev;
                // 产品保证金
                String product_security_deposit_c = cthList.get(i).getString("Product_Sequrity_Deposit_c");
                String psd = product_security_deposit_c == null ? "/\t" : product_security_deposit_c;
                builder.append(i + 1).append("\t").append(hName).append(nameTemp)
                        .append(hospital_integral_c).append("\t\t")//分值
                        .append(dev2).append("\r\n");//开发时限

                // 目标医院 id
                thIdList.add(cthList.get(i).getString("id"));

            }
            data.append("[<目标医院名单>]=").append(builder);
        } else {
            data.append("[<目标医院名单>]=/");
        }
        System.out.println("处理【合同目标医院】结束");

        Map<String, String> startAndEndTime = getStartAndEndTime(start_date_c, end_date_c);

        // 遍历 销售指标
        System.out.println("处理【销售指标】中...");
        // 查询销售指标
        List<JSONObject> dpList = BiologicalApiUtil.getSaleTarget(zohoRecord.getAccessToken(), contractId);
        if (dpList.size() > 0) {
            // 正序排序
            dpList.sort(Comparator.comparingInt(x -> Integer.parseInt(x.getString("Year_c")) + Integer.parseInt(x.getString("Month_c"))));
            BigDecimal ds = new BigDecimal(0);
            data.append("[<销售指标>]=");
            int time = 1;
            for (JSONObject dp : dpList) {
                //System.out.println("处理条数 = " + time++);
                // 年
                String year_c = dp.getString("Year_c");
                // 月
                String month_c = dp.getString("Month_c");
                // 销售指标
                String target_c = dp.getString("Target_c");
                data.append(checkString(year_c)).append("年")
                        .append(checkString(month_c)).append("月")
                        .append("\t\t\t\t\t\t\t").append(checkString(target_c)).append("\r\n");
                BigDecimal num;
                if (StringUtils.isBlank(target_c)) {
                    num = new BigDecimal(0);
                } else {
                    num = new BigDecimal(target_c);
                }

                ds = ds.add(num);
            }
            data.append("[<销售指标合计>]=").append(ds);
        } else {
            data.append("[<销售指标>]=/");
            data.append("[<销售指标合计>]=/");
        }
        System.out.println("处理【销售指标】结束");

        // 查询合同开发指标
        List<JSONObject> cdliList = BiologicalApiUtil.getDevelopTarget(zohoRecord.getAccessToken(), contractId);

        // 遍历 开发指标

        System.out.println("处理【开发指标】中...");
        if (cdliList.size() > 0) {
            // 正序排序
            cdliList.sort(Comparator.comparingInt(x -> Integer.parseInt(x.getString("Year_c")) + Integer.parseInt(x.getString("Month_c"))));

            BigDecimal ds = new BigDecimal(0);
            data.append("[<开发指标>]=");
            int time = 1;
            for (JSONObject cd : cdliList) {
                // 年
                String year_c = cd.getString("Year_c");
                // 月
                String month_c = cd.getString("Month_c");
                // 开发指标
                String developmentIndex_c = cd.getString("DevelopmentIndex_c");
                data.append(checkString(year_c)).append("年")
                        .append(checkString(month_c)).append("月")
                        .append("\t\t\t\t\t\t\t").append(checkString(developmentIndex_c)).append("\r\n");
                BigDecimal num = new BigDecimal(developmentIndex_c);
                ds = ds.add(num);
            }
            data.append("[<开发指标合计>]=").append(ds);
        } else {
            data.append("[<开发指标>]=/");
            data.append("[<开发指标合计>]=/");
        }
        System.out.println("处理【开发指标】结束");

        JSONStu.append("\"Data\":\"").append(data).append("\"}");

        String url = "";
        try {
            url = "http://" + tokenMap.get("httpServerIP") + ":" +
                    tokenMap.get("httpPort") + "/?Op=" + op +
                    "&ZTIdx=" + tokenMap.get("zTIdx") +
                    "&Token=" + tokenMap.get("token")
                    + "&APIClass=" + aPIClass + "&FileRtn=" + fileRtn;
        } catch (Exception e) {
            log.error(" e:" + e);
        }
        log.info(" JSONStu:" + JSONStu.toString());
        Map<String, Object> resMap = HttpUtil.postJsonData(url, JSONStu.toString());

        if (checkResponseMap(resMap)) return ResultUtil.error("请求接口不通！");
        String workIDs = resMap.get("WorkIDs").toString();
        log.info("workIDs=" + workIDs);

        // 第三步 获取downFiles
        List<String> downFiles = getDownFiles(workIDs, tokenMap);

        // 第四步 生成文件
        // 模板增加乙方名称
        contractName = bName + "_" + contractName;
        generatorFile(downFiles, tokenMap, contractId, contractName);

        // 删除之前缓存的文件
        deleteFile();

        return ResultUtil.success();

    }

    @Async("asyncPoolTaskExecutor")
    @SneakyThrows
    @Override
    public ResultUtil<String> incentiveTemplate(String incentiveId, String operationId) {
        log.info("incentiveId = {},operationId = {}", incentiveId, operationId);
        if (StringUtils.isBlank(incentiveId) || StringUtils.isBlank(operationId)) {
            return ResultUtil.error("入参为空");
        }
        ResultUtil<String> resultUtil;

        // 1 校验条件，当前操作人
        boolean isCheck = false;
        List<JSONObject> userData = CrmApiUtil.getUserDataById(zohoRecord.getAccessToken(), operationId);
        if (!CollectionUtils.isEmpty(userData)) {
            JSONObject user = userData.get(0);
            JSONObject profile = user.getJSONObject("profile");
            if (Objects.nonNull(profile)) {
                String roleName = profile.getString("name");
                log.info("当前用户角色名称：" + roleName);
                if (roleName.equalsIgnoreCase("客服助理") ||
                        roleName.equalsIgnoreCase("发货组客服组长") ||
                        roleName.equalsIgnoreCase("购销服务部经理") ||
                        roleName.equalsIgnoreCase("系统管理员") ||
                        roleName.equalsIgnoreCase("Administrator")) {
                    isCheck = true;
                }
            }
        }

        if (isCheck) {
            // 2 获取token
            Map<String, Object> tokenMap = getToken();
            if (tokenMap.containsKey("ERROR")) {
                return ResultUtil.error((String) tokenMap.get("ERROR"));
            }
            // 3 过滤合同数据，根据id循环调试，是否生成文件，获取文件流
            // 开发对赌协议
            resultUtil = generateTempData(incentiveId, tokenMap);
        } else {
            return ResultUtil.error("当前用户角色没有权限");
        }
        return resultUtil;
    }


    private ResultUtil<String> generateTempData(String incentiveId, Map<String, Object> tokenMap) {
        //System.out.println("zohoRecord.getAccessToken() = " + zohoRecord.getAccessToken());
        ResultUtil<String> result = ResultUtil.success();
        String op = "21";
        String aPIClass = "TGFWXY001";
        String models = "2022年开发对赌协议（三方协议）-v1.3";
        String fileRtn = "0";

        // 开发上量奖励
        JSONObject incentiveCrmData = BiologicalApiUtil.getIncentiveData(zohoRecord.getAccessToken(), incentiveId);

        // 初始开发保证金
        String field14 = incentiveCrmData.getString("DevelopmentSequrityDeposit_c");

        // 合同名称
        JSONObject Contract_c = incentiveCrmData.getJSONObject("Contract_c");
        String contractName = Contract_c.getString("name");

        // 合同id
        String contractId = Contract_c.getString("id");
        JSONObject contractData = BiologicalApiUtil.getContractData(zohoRecord.getAccessToken(), contractId);

        // 合同编号
        String contractCode_c = contractData.getString("ContractCode_c");

        // 合同里的推广产品（包装包材）的id
        JSONObject agent_product_package_c = contractData.getJSONObject("Agent_Product_Package_c");
        String packageId = agent_product_package_c.getString("id");

        // 包装包材
        List<JSONObject> packageList = BiologicalApiUtil.getPackingMaterial(zohoRecord.getAccessToken(), packageId);
        // 件装规格
        String packingUnit_c = "";
        // 生产企业
        String Manufacturer__c = "";
        // 通用名
        String commonName = "";
        if (packageList.size() > 0) {
            JSONObject pw = packageList.get(0);
            // 件装规格
            packingUnit_c = pw.getString("PackingUnit_c");
            // 生产企业
            Manufacturer__c = pw.getString("Manufacturer_c");
            // 通用名
            JSONObject drugs_c = pw.getJSONObject("Drugs_c");
            if (Objects.nonNull(drugs_c)) {
                commonName = drugs_c.getString("name");
            }
        }

        // 目标医院名称
        String hospitalName = "";
        //开发时限
        String field52 = incentiveCrmData.getString("Time_Limit_c");
        // 查询开发上量奖励目标医院
        List<JSONObject> hosList = BiologicalApiUtil.getIncentiveTargetHospital(zohoRecord.getAccessToken(), incentiveId);

        if (hosList.size() > 0) {
            JSONObject jsonObject = hosList.get(0);
            JSONObject targetHospital_c = jsonObject.getJSONObject("TargetHospital_c");
            // 目标医院名称
            hospitalName = targetHospital_c.getString("name");
            field52 = targetHospital_c.getString("Time_Limit_c");
        }


        // 销售总监
        String personName = "";
        JSONObject field38 = incentiveCrmData.getJSONObject("Sales_Director_c");
        if (Objects.nonNull(field38)) {
            personName = field38.getString("name");
        }

        // 乙方-签约人
        String yiPersonName = "";
        JSONObject field36 = incentiveCrmData.getJSONObject("Two_Part1_c");
        if (Objects.nonNull(field36)) {
            yiPersonName = field36.getString("name");
        }
        // 乙方-联系电话
        String field6 = incentiveCrmData.getString("Two_Part_Phone_c");

        // 协议签订方式
        String methodOfAgreement = incentiveCrmData.getString("Method_of_agreement");
        boolean isTwo = false;
        if (methodOfAgreement.equals("两方协议")) {
            isTwo = true;
        }
        // 丙方-签约人
        String bingPersonName = "";
        JSONObject field69 = incentiveCrmData.getJSONObject("The_Third_Party_c");
        if (Objects.nonNull(field69)) {
            bingPersonName = field69.getString("name");
        }
        // 丙方-联系电话
        String field4 = incentiveCrmData.getString("The_Third_Party_Phone_c");
        // 目标销量
        String field5 = incentiveCrmData.getString("TargetQuantity_c");
        // 补充条款
        String field19 = incentiveCrmData.getString("SupplementaryTerms_c");

        StringBuilder data = new StringBuilder("[<甲方名称>]=" + personName
                + "[<乙方名称>]=" + yiPersonName
                + "[<乙方电话>]=" + checkString(field6)
                //+ "[<丙方名称>]=" + bingPersonName
                //+ "[<丙方电话>]=" + checkString(field4)
                + "[<产品通用名>]=" + commonName
                + "[<产品规格>]=" + packingUnit_c
                + "[<产品生产厂家>]=" + Manufacturer__c
                + "[<目标医院信息名单>]=" + hospitalName
                + "[<开发时限>]=" + checkString(field52)
                + "[<开发保证金>]=" + field14
                + "[<目标销量>]=" + checkString(field5)
                + "[<补充条款>]=" + checkString(field19)
                + "[<合同协议编号>]=" + checkString(contractCode_c)
        );

        if (!isTwo) {
            data.append("[<丙方名称>]=").append(bingPersonName);
            data.append("[<丙方电话>]=").append(checkString(field4));
        }


        log.info("models=" + models);
        String jsonStu = getJsonStu(models, data);

        String url = "";
        try {
            url = "http://" + tokenMap.get("httpServerIP") + ":" +
                    tokenMap.get("httpPort") + "/?Op=" + op +
                    "&ZTIdx=" + tokenMap.get("zTIdx") +
                    "&Token=" + tokenMap.get("token")
                    + "&APIClass=" + aPIClass + "&FileRtn=" + fileRtn;
        } catch (Exception e) {
            log.error("error:" + e);
        }

        Map<String, Object> resMap = HttpUtil.postJsonData(url, jsonStu);

        if (checkResponseMap(resMap)) return ResultUtil.error("请求接口不通！");
        String workIDs = resMap.get("WorkIDs").toString();
        log.info("workIDs=" + workIDs);

        // 第三步 获取downFiles
        List<String> downFiles = getDownFiles(workIDs, tokenMap);

        // 第四步 生成文件
        // 模板增加乙方名称
        contractName = yiPersonName + "_" + contractName;
        generatorIncentiveFile(downFiles, tokenMap, incentiveId, contractName);

        // 删除之前缓存的文件
        deleteFile();
        return result;
    }

    public String checkString(String str) {
        if (StringUtils.isBlank(str)) {
            return "/";
        } else {
            return str;
        }

    }

    @Override
    public void test() {

        System.out.println("zohoRecord.getAccessToken() = " + zohoRecord.getAccessToken());

        // 文件流方式
        String url = "https://www.zohoapis.com.cn/crm/v3/TargetHospitalSaleTargetChangeList/" + "199864000016668200" + "/Attachments";

        String fileFullPath = "D:\\code\\biological\\src\\main\\resources\\wordTemplate\\目标医院销售指标变更明细模板.pdf";
        JSONObject jsonObject = HttpUtil.postFileByFileStream(zohoRecord.getAccessToken(), fileFullPath, url);
        System.out.println(jsonObject.toJSONString());
    }


}
